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;
    }
};
posted on 2020-09-14 23:02  Ricochet!  阅读(188)  评论(0编辑  收藏  举报