1. 程式人生 > 實用技巧 >5.二叉樹遍歷

5.二叉樹遍歷

二叉樹的資料結構

struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode() : val(0), left(nullptr), right(nullptr) {}
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
    TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};
 

先序遍歷

Leetcode 144. Binary Tree Preorder Traversal

//先序遞迴
class Solution {
public:
    
    vector<int> preorderTraversal(TreeNode* root) {
        if(root==NULL) return vector<int>{};
        vector<int> res;
        preorderTree(root, res);
        return res;
    }
    void preorderTree(TreeNode* node, vector<int> &res){
        if(node==NULL) return;
        res.push_back(node->val);
        preorderTree(node->left, res);
        preorderTree(node->right, res);
    }
};
//先序非遞迴
class Solution {
public:
    
    vector<int> preorderTraversal(TreeNode* root) {
        if(root==NULL) return vector<int>{};
        vector<int> res;
        stack<TreeNode*> st;
        st.push(root);
        TreeNode *node=NULL;
        while(!st.empty()){
            node = st.top();
            st.pop();
            res.push_back(node->val);
            if(node->right) st.push(node->right);
            if(node->left) st.push(node->left);
        }
        return res;
    }
};

中序遍歷

leetcode 94. Binary Tree Inorder Traversal

//中序遞迴
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> ans;
        inorderTree(root, ans);
        return ans;
    }
    void inorderTree(TreeNode *node, vector<int> &ans){
        if(node==NULL) return;
        inorderTree(node->left, ans);
        ans.push_back(node->val);
        inorderTree(node->right, ans);
    }
};
//中序非遞迴
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        if(root==NULL) return vector<int>{};
        vector<int> res;
        stack<TreeNode*> st;
        TreeNode *node=root;
        while(!st.empty() || node){
            if(node!=NULL){
                st.push(node);
                node=node->left;
            }else{
                node = st.top();
                st.pop();
                res.push_back(node->val);
                node=node->right;
            }
        }
        return res;
    }
};

後序遍歷

  1. Binary Tree Postorder Traversal
//後序遞迴
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        postorderTree(root, res);
        return res;
    }
    void postorderTree(TreeNode* node, vector<int> &res){
        if(node==NULL) return;
        postorderTree(node->left, res);
        postorderTree(node->right, res);
        res.push_back(node->val);
    }
};
//後序非遞迴
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        if(root==NULL) return vector<int>{};
        vector<int> res;
        stack<TreeNode*> st1;
        stack<TreeNode*> st2;
        st1.push(root);
        TreeNode *node = NULL;
        while(!st1.empty()){
            node = st1.top();
            st2.push(node);
            st1.pop();
            if(node->left) st1.push(node->left);
            if(node->right) st1.push(node->right);
        }
        while(!st2.empty()){
            node = st2.top();
            st2.pop();
            res.push_back(node->val);
        }
        return res;
    }
};

層序遍歷

  1. Binary Tree Level Order Traversal
//層序遍歷遞迴
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(root==NULL) return vector<vector<int>>();
        vector<vector<int>> ans;
        level(ans, root, 0);
        return ans;
    }
    void level(vector<vector<int>> &ans, TreeNode *root, int depth){
        if(ans.size()==depth) ans.push_back(vector<int>());
        ans[depth].push_back(root->val);
        if(root->left) level(ans, root->left, depth+1);
        if(root->right) level(ans, root->right, depth+1);
    }
};
//層序遍歷非遞迴
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        if(root==NULL) return vector<vector<int>>();
        vector<vector<int>> ans;
        int idx=0;
        queue<TreeNode*> q;
        q.push(root);
        while(!q.empty()){
            int size=q.size();
            TreeNode *node=NULL;
            ans.push_back(vector<int>());
            while(size--){
                node = q.front();
                q.pop();
                ans[idx].push_back(node->val);
                if(node->left) q.push(node->left);
                if(node->right) q.push(node->right);
            }
            idx++;
        }
        return ans;
    }
};

右視樹

  1. Binary Tree Right Side View
//右視樹遞迴實現
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        if(root==NULL) return vector<int>();
        vector<int> ans;
        recursion(root, 1, ans);
        return ans;
    }
    void recursion(TreeNode *root, int depth, vector<int> &ans){
        if(root==NULL) return;
        if(ans.size()<depth) ans.push_back(root->val);
        recursion(root->right, depth+1, ans);
        recursion(root->left, depth+1, ans);
    }
};

非遞迴的版本和層序遍歷類似,只是將層序遍歷迴圈中的vector變為stack即可,內迴圈結束,取top即可。

之字樹

  1. Binary Tree Zigzag Level Order Traversal
class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        if(root==NULL) return vector<vector<int>>();
        vector<vector<int>> ans;
        queue<TreeNode *> q;
        q.push(root);
        bool Left2Right=true;
        while(!q.empty()){
            int size=q.size();
            vector<int> cur_vec(size);
            for(int i=0;i<size;i++){
                int idx = Left2Right?i:size-i-1;
                TreeNode * tmp = q.front();
                q.pop();
                cur_vec[idx] = tmp->val;
                if(tmp->left) q.push(tmp->left);
                if(tmp->right) q.push(tmp->right);
            }
            ans.push_back(cur_vec);
            Left2Right=!Left2Right;
        }
        return ans;
    }
};