zoukankan      html  css  js  c++  java
  • 二叉树的前序,中序,后序遍历的非递归实现

    注:本文内容参考左老师课程

    二叉树的遍历分为前、中、后序,对于递归的实现方法,这里不再赘述,本文主要介绍实现非递归的方法,其核心思想均是用栈来实现,其中着重说明后序遍历。

    前序遍历:相对容易

     1 //方法1
     2 void preOrderTraversal(TreeNode *root,vector<int> &pre){
     3         stack<TreeNode *> s;
     4         TreeNode *p = root;
     5         while(!s.empty() || p != NULL){
     6             while(p != NULL){
     7                 pre.push_back(p->val);
     8                 s.push(p);
     9                 p = p->left;
    10             }
    11             if(!s.empty()){
    12                 p = s.top();
    13                 s.pop();
    14                 p = p->right;
    15                 
    16             } 
    17         }        
    18     }
    19     //方法2
    20 void preOrderTraversal(TreeNode *root,vector<int> &pre){
    21         stack<TreeNode *> s;
    22         TreeNode *p = root;
    23         s.push(p);
    24         while(!s.empty()){
    25             p = s.top();
    26             s.pop();
    27             pre.push_back(p->val);
    28             if(p->right)
    29                 s.push(p->right);
    30             if(p->left)
    31                 s.push(p->left);
    32         }        
    33     }

    中序遍历:

     1     void inOrderTraversal(TreeNode *root,vector<int> &in){
     2         stack<TreeNode *> s;
     3         TreeNode *p = root;
     4         while(!s.empty() || p != NULL){
     5             while(p != NULL){
     6                 s.push(p);
     7                 p = p->left;
     8             }            
     9             p = s.top();
    10             in.push_back(p->val);
    11             s.pop();
    12             p = p->right;            
    13         }
    14     }

    后序遍历:

    方法1:使用两个栈实现(把先序访问的顺序用第二个栈存起来,然后再出栈就成了)

    具体过程如下:

    1.申请两个栈,记为s1,s2,然后将头节点压入s1中

    2.从s1中弹出栈顶节点,记为cur,然后先把cur的左孩子压入s1中,然后把cur的右孩子压入s1中

    3.在整个过程中,每一个从s1中弹出的节点都放入第二个栈s2中。

    4.不断重复步骤2和步骤3,直到s1为空,过程停止。

    5.从s2中依次弹出节点并打印,打印的顺序就是后序遍历的顺序了。

    代码如下:

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

    方法二:用一个栈来实现

    具体过程如下:

    1. 申请一个栈,记为s,将头节点压入s,同时设置两个变量cur和pre,在整个遍历过程中,cur代表当前s的栈顶节点,pre代表上一次访问的结点,初始时cur为NULL,pre为头节点
    2. 每次令cur等于当前s的栈顶节点,但不从栈中弹出节点,此时分以下三种情况:
      1. 如果cur的左孩子不为空,并且pre不等于cur的左孩子,也不等于cur的右孩子(代表左孩子存在,且左右孩子都没有访问过),则把cur的左孩子压入栈s中。
      2. 如果情况1不成立,并且cur的右孩子不为空,并且pre不等于cur的右孩子(代表其左孩子为空或者其已经访问过,但其右孩子没有访问过),则把cur的右孩子压入栈s中。
      3. 如果情况1和情况2都不成立,那么从s中弹出cur并打印,然后令pre等于cur。
    3. 一直重复步骤2,直到s为空,过程停止。
     1     void postOrderTraversal(TreeNode *root,vector<int> &post){
     2         stack<TreeNode *> s;
     3         TreeNode *cur = NULL;
     4         TreeNode *pre = root;  //注意这里的值
     5         s.push(root);
     6         while(!s.empty()){
     7             cur = s.top();
     8             if(cur->left && pre != cur->left && pre != cur->right)  
     9                 s.push(cur->left);
    10             else if(cur->right && pre != cur->right)
    11                 s.push(cur->right);
    12             else{
    13                 s.pop();
    14                 post.push_back(cur->val);
    15                 pre = cur;
    16             }
    17         }
    18     }
    只为训练自己,时刻锤炼一个程序员最基本的技能!
  • 相关阅读:
    簇索引与非簇索引在查询中的应用与分析(转载) dodo
    都是防火墙惹的祸:sqlserver连接服务器数据库提示注册失败 dodo
    C#中如何将字符串转换成流,同时如何将流转换成字符串? dodo
    dataType参数不能为空,未处理的“System.ArgumentNullException”类型的异常出现在 mscorlib.dll 中 dodo
    错误(Client does not support authentication protocol requested by server; consider upgrading MySQL client)? dodo
    php分页函数(转) dodo
    c#2.0匿名方法三(转) dodo
    ASP.NET 2.0 中改进的缓存功能(转) dodo
    解决apache服务器默认编码为西欧编码的问题 dodo
    常用的正则表达式 dodo
  • 原文地址:https://www.cnblogs.com/coding-wtf/p/5833775.html
Copyright © 2011-2022 走看看