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

    先来看一下递归版的后序遍历是怎么写的

    void dfs(TreeNode *root){
        if(root==NULL) return ;
        dfs(root->left);//左节点
        dfs(root->right);//右节点
        cout<<roo->val<<endl;//访问
    }

    可以看到,对于root,我们总是先访问root的left儿子,right儿子,然后再访问root,也就是说,我们第三次看到root时候再对它进行访问。

    非递归的思想其实是一样的,当我们第一次遇到root的时候,如果有左儿子,先将root搁置,然后去访问它的左儿子,再遇到root的时候再将它搁置,去访问它的右儿子,再三次遇到rootd的时候,访问root,所谓搁置,就是将该节点放到stack中,当某一个之路访问完毕后,也就是遇到NULL节点时,从stack中取出之前每访问的节点,然后再接着上次访问。

    记录某个节点出现的次数,我们可以借用map。

    code:

    class Solution {
        vector<int> ans;
    public:
        stack<TreeNode*>st;
        map<TreeNode*,int >mp;
        vector<int> postorderTraversal(TreeNode* root) {
            mp.clear();
            if(!root) return ans;
            TreeNode* mark=NULL;
            while(root||st.size()){
                if(root){//第一次遇到root,访问它的左儿子
                    st.push(root);
                    mp[root]++;
                    root=root->left;
                }
                else {
                    while(st.size()){
                        TreeNode* p=st.top();
                        st.pop();
                        if(mp[p]==2||p->right==NULL){//如果说第三次遇到p,或者说该节点没有右节点,那么可以直接访问
                            ans.push_back(p->val);
                        }
                        else {//说明第二次遇到右儿子,访问右节点
                            mp[p]++;
                            st.push(p);
                            root=p->right;
                            break;
                        }
                    }
                }
            }
            return ans;
        }
    };

    除了用map记录外,还有一个十分巧妙的方法,如果说我们这次对root进行了访问,那么上次是对谁访问的?,一定是root->right,所以我们可以再访问root的同时对root记录一下,然后下次判断该节点是否可以访问的时候直接判断mark是否等于该节点的右儿子即可。

    class Solution {
        vector<int> ans;
    public:
        stack<TreeNode*>st;
        vector<int> postorderTraversal(TreeNode* root) {
            mp.clear();
            if(!root) return ans;
            TreeNode* mark=NULL;
            while(root||st.size()){
                if(root){
                    st.push(root);
                    root=root->left;
                }
                else {
                    while(st.size()){
                        TreeNode* p=st.top();
                        st.pop();
                        if(p->right==mark||p->right==NULL){
                            ans.push_back(p->val);
                            mark=p;
                        }
                        else {
                            st.push(p);
                            root=p->right;
                            break;
                        }
                    }
                }
            }
            return ans;
        }
    };
  • 相关阅读:
    Eclipse Java开发环境配置 + memcached + maven
    sqlserver数据库自动备份
    从表A中选择部分字段插入到表B
    电信IOT平台关于产品profile插件的添加流程
    SQLServer查询耗时sql语句
    net core 包管理
    byte[] 截串操作
    关于kafka启动失败问题
    springboot 搭建maven项目
    C# MongoDB学习之路(一)
  • 原文地址:https://www.cnblogs.com/Accepting/p/13752201.html
Copyright © 2011-2022 走看看