二叉树非递归遍历

Posted wsw_seu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树非递归遍历相关的知识,希望对你有一定的参考价值。

一、非递归先序遍历:先遍历根节点,后左,再右。先访问即任一节点,其可看作是根节点,因此可以直接访问;访问之后,若其左孩子不为空,按相同的规则访问他的左子树。

当访问其左子树,再访问其右子树,处理过程如下:

1、访问节点cur,将其入栈;

2、判断节点cur的左孩子是否为空,若为空,则取栈顶节点出栈,并将其右孩子置为当前访问节点。

3、若不为空,则循环将其左孩子置为当前节点。

 

注意:访问结点的位置要在循环中,先访问。

 

 1 void PreOrder(TreeNode* root,vector<int>& res)
 2 {
 3     stack<TreeNode*> s;
 4     TreeNode* cur=root;
 5     while (!s.empty() || cur)
 6     {
 7         while (cur)
 8         {
 9             res.push_back(cur->val);
10             s.push(cur);
11             cur = cur->left;
12         }
13         if (!s.empty())
14         {
15             cur = s.top();
16             s.pop();
17             cur = cur->right;
18         }
19     }
20 
21 }

 

2、非递归中序遍历:根据中序遍历的要求,优先访问其左孩子,而左孩子节点又可以看作是一根节点,然后继续访问其左孩子,直到遇到左孩子节点为空才进行访问,然后按相同规则访问右子树。

对于节点cur ,若其左孩子不为空,则将cur入栈,并将其左孩子置为当前cur.然后当前cur做出相同处理。

若其左孩子为空,则取栈顶元素并进行出栈,访问该栈顶元素,然后将当前cur的右孩子置为cur.

 

注意:主要是访问节点的时机同先序不同

void InOrder(TreeNode* root,vector<int>& res)
{
	stack<TreeNode*> s;
	TreeNode* cur=root;
	while (!s.empty() || cur)
	{
		while (cur)
		{
			s.push(cur);
			cur = cur->left;
		}
		if (!s.empty())
		{
			cur = s.top();
			res.push_back(cur->val);//先访问左孩子。不是在入栈过程中访问了
			s.pop();
			cur = cur->right;
		}
	}

}

  

3、非递归后序遍历:后序遍历中要保证左孩子和右孩子都已经被访问过并且左孩子在右孩子之前访问才能访问根节点。

要保证根节点在左右子树访问之后才能访问因此对于任意节点cur,先将其入栈。

1、如果cur不存在左孩子和右孩子则直接访问。

2、如果cur存在左孩子或者右孩子,但是左孩子或右孩子都已经被访问过了。

同样可以访问该节点,所以可以引入一个pre节点,存储前一次访问的节点。

如果不是上面的两种情况,则将cur的右孩子入栈

再将cur的左孩子入栈(一定要现将右孩子入栈)

 

 1 void PostOrder(TreeNode* root,vector<int>& res)
 2 {
 3     stack<TreeNode*> s;
 4     TreeNode* cur;
 5     TreeNode* pre = NULL;
 6     if (!root)  return;
 7     s.push(root);
 8     while (!s.empty())
 9     {
10         cur = s.top();
11         if (!cur->left&&!cur->right||(pre!==NULL&&(pre==cur->left||pre==cur->right)))
12         {
13             res.push_back(cur->val);
14             s.pop();
15             pre = cur;
16         }
17         else
18         {
19             if (cur->right)  s.push(cur->right);
20             if (cur->left)  s.push(cur->left);
21         }
22     }
23 
24 }

 

以上是关于二叉树非递归遍历的主要内容,如果未能解决你的问题,请参考以下文章

二叉树非递归遍历

创建二叉树非递归完成对二叉树的先序和后序遍历并遍历输出每一层的结点数查找结点P 和结点Q的最近共同祖先

二叉树非递归遍历

6)二叉树非递归遍历

遍历二叉树 非递归 JAVA 实现

重现二叉树非递归算法的构建过程