zoukankan      html  css  js  c++  java
  • 二叉树的非递归遍历

    递归转非递归 几乎都是用栈, 前序和中序遍历比较简单 ,后序遍历稍麻烦;

    1. 前序遍历 :

    void preDis(NODE* head)         //前序遍历
    {
        NODE* temp = head;
        stack<NODE*> st;
        while (temp != NULL||!st.empty())                    
        {
            while (temp != NULL)               //当前非空
            {
                cout<<temp->val<<' ';         //访问
                st.push(temp);                    //进栈 (可能有右子树)
                temp = temp->lchild;          //继续先序访问左子树
            }
            if (!st.empty())                           //栈非空
            {
                temp = st.top();                  //取头
                st.pop();
                temp = temp->rchild;         //访问头的右子树(进栈的元素都访问过了 但是右子树还没有)
            }
        }
    }

    2. 中序遍历:唯一和前序不同的是访问当前节点的时间

    void midDis(NODE* head)                   //中序遍历
    {
        NODE* temp = head;
        stack<NODE*> st;
        while (temp != NULL||!st.empty())
        {
            while (temp != NULL)            //当前非空
            {
                st.push(temp);                       //进栈
                temp = temp->lchild;             //左子树进栈
            }
            if (!st.empty())
            {
                temp = st.top();
                st.pop();
                cout<<temp->val<<' ';               //与前序的不同 再次出栈才访问
                temp = temp->rchild;
            }
        }
    }

    3. 后序遍历:

    比前两者都要麻烦的多,不过基本思路还是一样的,就是访问当前节点的时候,若当前节点没有子树,又或者当前节点的子树都已经访问过了,则可以访问当前节点;

    否则,将该节点的子树压栈(压栈的顺序是,先右子树,后左子树)

    void posDis(NODE* head)                    //后续
    {
        stack<NODE*>st;
        NODE* cur;                                            
        NODE* pre = NULL;
        st.push(head);
        while (!st.empty())
        {
            cur = st.top();
            if ((cur->lchild == NULL&&cur->rchild == NULL)||(pre != NULL&&(pre == cur->lchild||pre == cur->rchild)))    //当前结点没有子树或子树都被访问      
                                                                                                                                                                           //过了,才访问根节点
            {
                cout<<cur->val<<' ';
                st.pop();                                                                //访问过了就弹出栈
                pre = cur;                                                               //更新前一个访问的节点
            }
            else                                              //当前节点有子树 且没有被访问过
            {
                if (cur->rchild != NULL)              //右子树进栈
                {
                    st.push(cur->rchild);
                }
                if (cur->lchild != NULL)           //左子树进栈
                {
                    st.push(cur->lchild);
                }
            }
        }
    }
  • 相关阅读:
    Tomcat 部署Solr 5.2.1
    使用浮点类型导致计算误差以及判断误差
    Interface 接口
    ASP.NET 使用JQuery取后台数据并绑定到前台
    JavaScript代码应该放哪才最合适?
    Java学习笔记五(内部类 )
    Java学习笔记四(代码块 )
    Java学习笔记三(对象的基本思想一)
    Java学习笔记二(基础语法)
    Java学习笔记一(基础知识)
  • 原文地址:https://www.cnblogs.com/itachi7/p/2701132.html
Copyright © 2011-2022 走看看