【栈的应用】二叉树非递归中序遍历思想解析及代码实现

中序遍历的思想是在第二次经过结点的时候才去访问结点数据,要一直去寻找结点的左子树,访问完左子树在返回结点并获取结点数据,然后访问右子树,重复这个过程,也就是说如果当前结点有左子树就要转去左子树,访问完左子树才访问当前结点,这个场景刚好可以使用栈来实现,有左子树则把当前结点入栈,访问完左子树,再出栈并访问结点数据。非递归遍历算法的思想如下:

  • 步骤一:
    • 定义一个当前指针,并指向根结点,当前指针指向的结点称为当前结点;
  • 步骤二:
    • 如果当前结点有左子树,那么当前结点入栈,当前指针指向当前结点的左子树;
    • 如果当前结点没有左子树,访问当前结点数据;
  • 步骤三:
    • 当前结点右子树非空,当前指针指向当前结点右子树,转步骤二;
    • 当前结点右子树为空且栈非空,返回并弹出栈顶元素给当前指针,访问当前结点,当前指针指向当前结点右子树,转步骤二;
    • 当前结点右子树为空,且栈为空,遍历结束。

根据这个步骤,非递归中序遍历的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;
		}
	}
}

下面创建一棵树来测试一下算法,二叉树如下

posted @ 2022-04-05 04:45  Mindtechnist  阅读(18)  评论(0编辑  收藏  举报  来源