• 二叉树非递归遍历


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

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

    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 }
  • 相关阅读:
    python 3.5下用户登录验证,三次锁定的编码
    Python之面向对象
    Python基础之模块
    Python基础之yield,匿名函数,包与re模块
    Python基础之函数
    Python基础之字符编码,文件操作流与函数
    Python基础之字符串,布尔值,整数,列表,元组,字典,集合
    Python基础之(判断,循环,列表,字典)
    mysql学习
    linux 下的 正则表达式(awk,sed,awk)学习
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/7821824.html
Copyright © 2020-2023  润新知