Leetcode 144. 二叉树的前序遍历 && 94.二叉树的中序遍历 && 145. 二叉树的后续遍历

思路:

递归 迭代

 

迭代框架:

// 模拟函数调用栈
private Stack<TreeNode> stk = new Stack<>();

// 左侧树枝一撸到底
private void pushLeftBranch(TreeNode p) {
    while (p != null) {
        /*******************/
        /** 前序遍历代码位置 **/
        /*******************/
        stk.push(p);
        p = p.left;
    }
}

public List<Integer> traverse(TreeNode root) {
    // 指向上一次遍历完的子树根节点
    TreeNode visited = new TreeNode(-1);
    // 开始遍历整棵树
    pushLeftBranch(root);

    while (!stk.isEmpty()) {
        TreeNode p = stk.peek();

        // p 的左子树被遍历完了,且右子树没有被遍历过
        if ((p.left == null || p.left == visited) 
          && p.right != visited) {
            /*******************/
            /** 中序遍历代码位置 **/
            /*******************/
            // 去遍历 p 的右子树
            pushLeftBranch(p.right);
        }
        // p 的右子树被遍历完了
        if (p.right == null || p.right == visited) {
            /*******************/
            /** 后序遍历代码位置 **/
            /*******************/
            // 以 p 为根的子树被遍历完了,出栈
            // visited 指针指向 p
            visited = stk.pop();
        }
    }
}

 

前序遍历

递归

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        traverse(root);
        return seq;
    }
    void traverse(TreeNode* root){
        if(root==nullptr){
            return;
        }
        seq.push_back(root->val);
        traverse(root->left);
        traverse(root->right);
    }
    vector<int> seq;
};

 

迭代

class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        TreeNode* visited=new TreeNode(-1);
        pushLeft(root);
        while(!s.empty()){
            TreeNode* p=s.top();
            if((p->left==nullptr||p->left==visited)
                &&p->right!=visited){
                pushLeft(p->right);
            }
            if(p->right==nullptr||p->right==visited){
                visited=s.top();
                s.pop();
            }
        }
        return ret;
    }
    void pushLeft(TreeNode* root){
        while(root!=nullptr){
            ret.push_back(root->val);
            s.push(root);
            root=root->left;
        }
    }
    vector<int> ret;
    stack<TreeNode *> s;
};

 

中序遍历

递归

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        traverse(root);
        return ret;
    }
    void traverse(TreeNode* root){
        if(root==nullptr){
            return;
        }
        traverse(root->left);
        ret.push_back(root->val);
        traverse(root->right);
    }
    vector<int> ret;
};

 

迭代

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        TreeNode* visited=new TreeNode(-1);
        pushLeft(root);
        while(!s.empty()){
            TreeNode* p=s.top();
            if((p->left==nullptr||p->left==visited)
            &&p->right!=visited){
                ret.push_back(p->val);
                pushLeft(p->right);
            }
            if(p->right==nullptr||p->right==visited){
                visited=s.top();
                s.pop();
            }
        }
        return ret;
    }
    void pushLeft(TreeNode* root){
        while(root!=nullptr){
            s.push(root);
            root=root->left;
        }
    }
    vector<int> ret;
    stack<TreeNode*> s;
};

 

后续遍历

递归

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        traverse(root);
        return ret;
    }
    void traverse(TreeNode* root){
        if(root==nullptr){
            return;
        }
        traverse(root->left);
        traverse(root->right);
        ret.push_back(root->val);
    }
    vector<int> ret;
};

 

迭代

思路:先将左结点都放进去,如果左节点空了或者左节点遍历过了,就将右子树遍历。当右结点空了或者也遍历过了。就记录根节点,并出栈。

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        TreeNode* visited=new TreeNode(-1);
        pushLeft(root);
        while(!s.empty()){
            TreeNode* p=s.top();
            if((p->left==nullptr||p->left==visited)
            &&p->right!=visited){
                pushLeft(p->right);
            }
            if(p->right==nullptr||p->right==visited){
                ret.push_back(p->val);
                visited=s.top();
                s.pop();
            }
        }
        return ret;
    }
    void pushLeft(TreeNode* root){
        while(root!=nullptr){
            s.push(root);
            root=root->left;
        }
    }
    vector<int> ret;
    stack<TreeNode*> s;
};

 

posted @ 2022-02-16 11:56  鸭子船长  阅读(29)  评论(0编辑  收藏  举报