• 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;
        }
    };
  • 相关阅读:
    c语言博客作业09
    c语言|博客作业08
    C语言|博客作业07
    C语言|博客作业06
    C语言|博客作业05
    C语言|博客作业04
    C语言|博客作业03
    关于Vue.js里面输入框在v-model之后如果给其绑定属性赋初始值导致绑定数据不响应问题
    前后端分离开发模式中关于前端取得分页数据时的分页问题(前端使用ant design pro)
    《电子病案在病案管理中存在问题及对策》文献阅读随笔
  • 原文地址:https://www.cnblogs.com/KakagouLT/p/13670027.html
Copyright © 2020-2023  润新知