• Leetcode 94 | 144 | 145


    三题都是二叉树遍历,只不过是遍历序的问题。

    三题都可以共用一个算法,取决于什么时候插入值。其中,【后序遍历】(左->右->根)可以通过【魔改的前序遍历】(根->右->左)的结果反转得到。

    迭代解决二叉树遍历,主要在于我要知道什么时候某棵子树遍历完了。

    例如,对于栈算法,我可以一直对左节点压栈。当节点被弹出,说明其左子树已经被访问完毕,于是访问其右子树。

    Morris 算法的思想是这样的:找到一个机制,让我们能知道左子树遍历完了。

    这个机制就是在【左子树的最右节点】插入一个右指针,使其指向根节点。

    这样的话,当最右节点试图访问它的右节点,就会回到根部。

    这时候,根部节点再次去尝试找【左子树的最右节点】,就会找到他自己。

    这时候他就知道左子树已经遍历完成,只需要把这个最右节点的连接切断就可以了。

    算法见下。后序遍历就在前序遍历的基础上,修改对应左右边即可。

    class Solution {
    public:
        vector<int> TraverseTemplate(TreeNode* root) {
            vector<int> ans;
            while(root != nullptr){
                if(root->left != nullptr){
                    TreeNode* pred = root->left;
                    while(pred->right != nullptr && pred->right != root) pred = pred->right;
                    
                    if(pred->right == nullptr){
                        // 对于前序,在这里插入
                        // ans.emplace_back(root->val);
                        pred->right = root;
                        root = root->left;
                    }
                    else{ // == root, visit back!
                        // 对于中序,在这里插入
                        // ans.emplace_back(root->val);
                        pred->right = nullptr;
                        root = root->right;
                    }
                }
                else{
                    ans.emplace_back(root->val);
                    root = root->right;
                }
            }
            return ans;
        }
    };        
    class Solution {
    public:
        vector<int> inorderTraversal(TreeNode* root) {
            vector<int> ans;
            while(root != nullptr){
                if(root->left != nullptr){
                    TreeNode* pred = root->left;
                    while(pred->right != nullptr && pred->right != root) pred = pred->right;
                    
                    if(pred->right == nullptr){
                        pred->right = root;
                        root = root->left;
                    }
                    else// == root, visit back!
                        ans.emplace_back(root->val);
                        pred->right = nullptr;
                        root = root->right;
                    }
                }
                else{
                    ans.emplace_back(root->val);
                    root = root->right;
                }
            }
            return ans;
        }
    };
  • 相关阅读:
    代码—五天前是星期几
    随手笔记-日期
    建造曲线记忆表格
    2017-5-10随手记
    java-web——第一课 tomcat
    复习
    Leetcode 24. Swap Nodes in Pairs(详细图解一看就会)
    这可能是最详细的解析HTTP走私攻击的文章
    使用grub2引导进入Linux或Window系统
    ACM集训第一次积分赛赛前复习+day4
  • 原文地址:https://www.cnblogs.com/KakagouLT/p/13670027.html
Copyright © 2020-2023  润新知