美文网首页
非递归方法二叉树遍历

非递归方法二叉树遍历

作者: 锦绣拾年 | 来源:发表于2021-10-04 23:05 被阅读0次

后序遍历非递归法

后续遍历,非递归法相对于前中序稍微复杂一点,因为它需要记录当前节点是否已经遍历过了。

三种方法:1)使用prev,记录输出的前一个节点 2)使用visible方法【直接记录当前节点是否访问过】。

3)对于这些非递归法,都可以使用颜色法【准备第二个栈,表示当前节点是否访问过,若访问过,直接输出】。

1.常规方法

左中右、左中右、左右中。

都是先对左节点做处理,因此可以先把左节点放到栈里。

然后取出一个节点,考虑处理右节点。【比较难理解】

需要注意

主要元素:栈、root

root 当前待遍历节点。 栈:取出下一个节点

如果右节点没有的话,或者无需向右遍历,那就把root置为空指针

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        //左右中
        stack<TreeNode* > mem;
        vector<int>res;
        if(!root)
            return res;
        TreeNode* pre=nullptr;
        while(root||!mem.empty()){
            while(root){//先把root左节点加入
                mem.push(root);
                root=root->left;
            }
            root=mem.top();
            mem.pop();
            //加右节点,前提
            if(root->right==pre||root->right==nullptr){//右节点已经遍历
                res.push_back(root->val);
                pre=root;
                root=nullptr;
            }else{//右节点先处理
                mem.push(root);
                root=root->right;

            }

            //可以用visible来表示,不用visible就得用pre指针

        }
        return res;

    }
};

2.使用visible思路,而非prev指针。

总之先遍历每一个节点的左树。然后对当前情况分组处理。1.是当前节点已被访问过。直接输出。否则,先看当前节点和它的右节点。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        //左右中
        stack<TreeNode* > mem;
        map<TreeNode* ,int> a;
        vector<int>res;
        if(!root)
            return res;
        TreeNode* pre=nullptr;
        while(root||!mem.empty()){
            while(root){//先把root左节点加入
                mem.push(root);
                a[root]=1;
                root=root->left;
            }
        
            root=mem.top();
            mem.pop();
            if(a[root]>1||!root->right){
                res.push_back(root->val);
                root=nullptr;
            }else{
                mem.push(root);
                a[root]=2;
                root=root->right;
            }
            
        }
        return res;

    }
};

3.颜色标记法。【实际上是中右左换成左右中】

可以使用两个栈,或者使用pair对。

左右中——》重新push时是 中左右,入栈。

开始先把节点push到栈中(但是只是辅助遍历,并不输出)

然后从栈中取出节点,按照中 左 右的顺序重新push(中节点,因为取出过一次,认为已经处理过,就标记处理过,再取出时直接输出就可),没有处理过的,继续按照中左右顺序遍历。

【这里新加一个栈,存标记,也可以用pair对】

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        //左右中

        stack<TreeNode*> res;
        stack<int> biaoji;
        vector<int> rr;
        if(!root)
            return rr;
        res.push(root);
        biaoji.push(1);
        
        TreeNode* tmp;
        int tmpb;
        while(!res.empty()){
            tmp=res.top();
            tmpb=biaoji.top();
            res.pop();
            biaoji.pop();
            //cout<<tmp->val<<"\t"<<tmpb<<endl;
            if(tmpb==1){
                res.push(tmp);
                biaoji.push(2);
                if(tmp->right){
                    res.push(tmp->right);
                    biaoji.push(1);
                }            
                if(tmp->left){
                    res.push(tmp->left);
                    biaoji.push(1);
                }                
                    
            }else{
                rr.push_back(tmp->val);

            }
        }
        return rr;

    }
};

前序遍历【中左右】

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root){
            return res;
        }//中左右
        stack<TreeNode*> tmp;
        while(root||!tmp.empty()){
            while(root){
                tmp.push(root);
                res.push_back(root->val);
                root=root->left;
            }
            root = tmp.top();
            tmp.pop();
            //看右
            if(root->right){
                root=root->right;
            }else{
                root=nullptr;
            }
            
        }
        return res;



    }
};

中序遍历【左中右】

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        if(!root){
            return res;
        }//左中右
        stack<TreeNode*> tmp;
        while(root||!tmp.empty()){
            while(root){
                tmp.push(root);
                
                root=root->left;
            }
            root = tmp.top();
            tmp.pop();
            res.push_back(root->val);
            //看右
            if(root->right){
                root=root->right;
            }else{
                root=nullptr;
            }
            
        }
        return res;
    }
};

相关文章

  • 二叉树遍历java,非递归、层次。

    /** * 前序遍历 * 递归 */ /*** 前序遍历* 非递归*/ 后续遍历非递归 二叉树层次遍历基于java...

  • 左神算法笔记——Morris遍历

    基本问题——实现二叉树的前序、中序、后序遍历 (递归、非递归,mirros方法) 递归 递归方式下的前中后遍历 非...

  • 二叉树递归非递归遍历算法整理

    一、二叉树前序遍历 1 前序递归遍历 2.前序非递归遍历 一、二叉树中序遍历 2.中序递归遍历 1.中序非递归遍历...

  • 总结

    1、二叉树广度遍历(非递归) 广度遍历非递归实现需要依靠一个队列。 2、二叉树深度遍历(递归与非递归,前序,中序和...

  • 二叉树遍历

    二叉树的遍历 1. 前序遍历 1.1 递归前序遍历 1.2 非递归前序遍历 2 中序遍历 2.1递归遍历 2.2非...

  • 二叉树遍历(先序、中序、后序)

    二叉树有多种遍历方法,有层次遍历、深度优先遍历、广度优先遍历等。 本文只涉及二叉树的先序、中序、后序的递归和非递归...

  • 二叉树非递归遍历(先序、中序、后序)

    二叉树有多种遍历方法,有层次遍历、深度优先遍历、广度优先遍历等。 本文只涉及二叉树的先序、中序、后序的递归和非递归...

  • 二叉树,非递归法

    递归法 二叉树的递归,有前序遍历、中序遍历、后序遍历,一般采用递归法,比较简单 非递归法 二叉树非递归法,采用栈来实现

  • 二叉树遍历-JAVA实现

    基础二叉树 二叉树遍历分为前序、中序、后序递归和非递归遍历、还有层序遍历。 前序递归遍历算法:访问根结点-->递归...

  • 算法之二叉树

    二叉树之C++实现 创建二叉树 复制二叉树 先序遍历 递归实现 非递归实现 中序遍历 递归实现 非递归实现 后序遍...

网友评论

      本文标题:非递归方法二叉树遍历

      本文链接:https://www.haomeiwen.com/subject/bilwnltx.html