• LC144/94/145 二叉树前序/中序/后序遍历 递归与非递归实现


    前序遍历

    递归写法

    class Solution {
    public:
        vector<int> preorderTraversal(TreeNode* root) {
            vector<int> res, leftRes, rightRes;
            if(root == nullptr)
                return res;
            res.push_back(root->val);
            leftRes = preorderTraversal(root->left);
            rightRes = preorderTraversal(root->right);
            if(leftRes.size() > 0)
            {
                for(auto val : leftRes)
                    res.push_back(val);
            }
            if(rightRes.size() > 0)
            {
                for(auto val : rightRes)
                    res.push_back(val);
            }
            return res;
        }
    };
    


    递归写法的时间复杂度,空间复杂度较为一般。

    非递归写法

    使用非递归写法时需要用到栈,这里采用了LC题解中一种不错的解法.
    思路:带有nullptr标记的节点直接访问节点值,没有标记则对节点本身添加标记并遍历子节点,该过程用栈实现

    class Solution {
    public:
        vector<int> preorderTraversal(TreeNode* root) {
            vector<int> res;
            if(root == nullptr)
                return res;
            stack<TreeNode*> nodes;
            nodes.push(root);
            while(nodes.size() > 0){
                TreeNode* nowNode = nodes.top();
                nodes.pop();
                if(nowNode != nullptr){
                    // 右
                    if(nowNode->right != nullptr)
                        nodes.push(nowNode->right);
                    // 左
                    if(nowNode->left != nullptr)
                        nodes.push(nowNode->left);
                    // 根
                    nodes.push(nowNode);
                    nodes.push(nullptr);
                }  
                else{
                    res.push_back(nodes.top()->val);
                    nodes.pop();
                }
            } 
            return res;
        }
    };
    

    这个题解的优点在于只需要交换 //右,//左,//根三部分的顺序即可实现先序/中序/后序遍历方式,非常方便.

    下图是一个遍历过程图示,可以更清晰地看到遍历过程。

    中序遍历

    递归写法

    class Solution {
    public:
        vector<int> inorderTraversal(TreeNode* root) {
            vector<int> res, leftRes, rightRes;
            if(root == nullptr)
                return res;
            leftRes = inorderTraversal(root->left);
            rightRes = inorderTraversal(root->right);
            if(!leftRes.empty()){
                for(auto val : leftRes)
                    res.push_back(val);
            }
            res.push_back(root->val);
            if(!rightRes.empty()){
                for(auto val : rightRes)
                    res.push_back(val);
            }
            return res;
        }
    };
    

    非递归写法

    参考前序遍历的非递归写法即可

    class Solution {
    public:
        vector<int> inorderTraversal(TreeNode* root) {
            vector<int> res;
            if(root == nullptr)
                return res;
            stack<TreeNode*> nodes;
            nodes.push(root);
            while(!nodes.empty()){
                TreeNode* nowNode = nodes.top();
                nodes.pop();
                if(nowNode != nullptr){
                    // 右
                    if(nowNode->right != nullptr)
                        nodes.push(nowNode->right);
                    // 根
                    nodes.push(nowNode);
                    nodes.push(nullptr);
                    // 左
                    if(nowNode->left != nullptr)
                        nodes.push(nowNode->left);
                }
                else{
                    res.push_back(nodes.top()->val);
                    nodes.pop();
                }
            }
            return res;
        }
    };
    

    后序遍历

    递归

    class Solution {
    public:
        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> res, left, right;
            if(root == NULL)
                return res;
            left = postorderTraversal(root->left);
            right = postorderTraversal(root->right);
            for(auto iter = left.begin(); iter != left.end(); iter ++)
                res.push_back(*iter);
            for(auto iter = right.begin(); iter != right.end(); iter ++)
                res.push_back(*iter);
            res.push_back(root->val);
            return res;
        }
    };
    

    非递归

    class Solution {
    public:
        vector<int> postorderTraversal(TreeNode* root) {
            vector<int> res;
            if(root == nullptr)
                return res;
            stack<TreeNode*> nodes;
            nodes.push(root);
            while(!nodes.empty()){
                TreeNode* nowNode = nodes.top();
                nodes.pop();
                if(nowNode != nullptr){        
                    // 根
                    nodes.push(nowNode);
                    nodes.push(nullptr);
                    // 右
                    if(nowNode->right != nullptr)
                        nodes.push(nowNode->right);
                    // 左
                    if(nowNode->left != nullptr)
                        nodes.push(nowNode->left);
                }
                else{
                    res.push_back(nodes.top()->val);
                    nodes.pop();
                }
            }
            return res;
        }
    };
    
  • 相关阅读:
    eslint 规则
    我的.eslintrc.js
    shell命令
    .sync 修饰符的理解
    【HNOI 2018】寻宝游戏
    【BZOJ 2820】YY的GCD
    【Luogu P2664】树上游戏
    【HAOI 2012】高速公路
    句摘
    【SCOI 2008】奖励关
  • 原文地址:https://www.cnblogs.com/imagineincredible/p/13294153.html
Copyright © 2020-2023  润新知