【栈的应用】二叉树非递归中序遍历思想解析及代码实现
中序遍历的思想是在第二次经过结点的时候才去访问结点数据,要一直去寻找结点的左子树,访问完左子树在返回结点并获取结点数据,然后访问右子树,重复这个过程,也就是说如果当前结点有左子树就要转去左子树,访问完左子树才访问当前结点,这个场景刚好可以使用栈来实现,有左子树则把当前结点入栈,访问完左子树,再出栈并访问结点数据。非递归遍历算法的思想如下:
- 步骤一:
- 定义一个当前指针,并指向根结点,当前指针指向的结点称为当前结点;
- 步骤二:
- 如果当前结点有左子树,那么当前结点入栈,当前指针指向当前结点的左子树;
- 如果当前结点没有左子树,访问当前结点数据;
- 步骤三:
- 当前结点右子树非空,当前指针指向当前结点右子树,转步骤二;
- 当前结点右子树为空且栈非空,返回并弹出栈顶元素给当前指针,访问当前结点,当前指针指向当前结点右子树,转步骤二;
- 当前结点右子树为空,且栈为空,遍历结束。
根据这个步骤,非递归中序遍历的C++代码实现如下:
void nonrecursive_traversal(MyTreeNode* tree)
{
stack<MyTreeNode*> s;
MyTreeNode* pStart = tree;
while (pStart->left != NULL)
{
//有左子树
s.push(pStart); //根结点入栈
pStart = pStart->left; //指针下移,指向左子树
}
while (pStart != NULL)
{
cout << pStart->data << " "; //没有左子树则访问
if (pStart->right != NULL)
{
//右子树非空
pStart = pStart->right;
while (pStart->left != NULL)
{
//有左子树
s.push(pStart); //根结点入栈
pStart = pStart->left; //指针下移,指向左子树
}
}
else if ((pStart->right == NULL) && (!s.empty()))
{
//右子树为空,且栈非空
pStart = s.top();
s.pop();
}
else
{
//右子树为空,且栈为空
pStart = NULL;
}
}
}
下面创建一棵树来测试一下算法,二叉树如下