Leetcode之二叉树遍历总结

一直想把二叉树的各种遍历做一个总结,在掌握好二叉树的4中遍历的基础上,其他的题目自然迎刃而解(可能有点夸张)。前、中、后序有递归和非递归的写法,一定要掌握,至于层序遍历嘛,直接非递归怼就是。

1. 前序遍历 Leetcode 144. Binary Tree Preorder Traversal

/*
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//递归实现
class Solution {
public:
    vector<int> preorderTraversal(TreeNode* root) {
        
        vector<int> res;
        
        if( root == NULL )
            return res;
        
        __preorderTraversal(root, res);
        return res;
            
    }
    
private:
    void __preorderTraversal(TreeNode* node, vector<int>& res){
        
        if( node == NULL )
            return;
        
        res.push_back(node->val);
        __preorderTraversal(node->left, res);
        __preorderTraversal(node->right, res);
        
        return;
    }
};

//非递归实现
class Solution {

public:
    vector<int> preorderTraversal(TreeNode* root) {

        vector<int> res;
        
        if(root == NULL)
            return res;

        stack<TreeNode*> stack;
        TreeNode* cur = root;
        while(cur != NULL || !stack.empty()){
            while(cur != NULL){
                res.push_back(cur->val);
                stack.push(cur);
                cur = cur->left;
            }

            cur = stack.top();
            stack.pop();
            cur = cur->right;
        }
        return res;
    }
};

2. 中序遍历 Leetcode 94. Binary Tree Inorder Traversal

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//递归实现
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        
        vector<int> res;
        if(root == NULL)
        	return res;
        __inorderTraversal(root, res);
        
        return res;
    }
    
private:
    void __inorderTraversal(TreeNode* node, vector<int>& res){
        
       if(node == NULL)
           return;
           
        __inorderTraversal(node->left, res);
        res.push_back(node->val);
        __inorderTraversal(node->right, res);
        
        return;
    }
};

//非递归实现
class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        
        vector<int> res;
        if( root == NULL )
            return res;
        
        stack<TreeNode*> stack;
        TreeNode* cur = root;
        
        while( cur != NULL || !stack.empty() ){
            
            while( cur != NULL ){
                stack.push( cur );
                cur = cur->left;
            }
            
            cur = stack.top();
            stack.pop();
            res.push_back( cur->val );
            cur = cur->right;
        }
        
        return res;
    }
};

3. 后序遍历 Leetcode 145. Binary Tree Postorder Traversal

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//递归实现
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        
        vector<int> res;
        if( root == NULL )
            return res;
        
        __postorderTraversal(root, res);
        return res;
        
    }
    
private:
    void __postorderTraversal(TreeNode* node, vector<int>& res){
        
        if( node == NULL )
            return;
        
        __postorderTraversal(node->left, res);
        __postorderTraversal(node->right, res);
        res.push_back( node->val );
        
        return;
    }
};

//非递归实现
class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        
        vector<int> res;
        if( root == NULL )
            return res;
        
        stack<TreeNode*> stack;
        TreeNode* pre = NULL;
        TreeNode* cur = root;
        
        while( cur != NULL || !stack.empty() ){
            
            while( cur != NULL ){
                
                stack.push( cur );
                cur = cur->left;
            }
            
                cur = stack.top();
                stack.pop();
                
                if( cur->right == NULL || pre == cur->right ){
                    
                    res.push_back( cur->val );
                    pre = cur;
                    cur = NULL;
                }
                else{
                    
                    stack.push(cur);
                    cur = cur->right;
                }
        }
        
        return res;
    }
};

4. 层序遍历 102. Binary Tree Level Order Traversal

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

//迭代实现
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        
        vector<vector<int>> res;
        
        if(root == NULL)
            return res;
        
        queue<TreeNode*> q;
        q.push(root);
        int level_num = 1;
        
        while( !q.empty() ){
            
            int new_level_num = 0;
            vector<int> level;
            
            for(int i = 0; i < level_num; i++){
                TreeNode* node = q.front();
                q.pop();
                level.push_back(node->val);

                if(node->left){
                    q.push(node->left);
                    new_level_num++;
                }
                if(node->right){
                    q.push(node->right);
                    new_level_num++;
                }
            }
            res.push_back(level);
            level_num = new_level_num;
        }
        
        return res;
    }
};

层序遍历有两变体:右视树和之字树。右视树就是站在一棵树的右边,看见的孩子,想法:开始就想到的是通过层序遍历来做,但是怎么得到每一层的最右边的孩子呢?当时想的是借鉴102,每一层用一个vector来存,然后通过for循环每次取最后一个值就好,但是发现有点麻烦,,,就没动手。后面发现用stack来存,后面直接top()就简单多了。

右视树 Leetcode 199. Binary Tree Right Side View
直接在102的基础上将vector换成了stack

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        
        vector<int> res;
        
        if(root == NULL)
            return res;
        
        queue<TreeNode*> q;
        q.push(root);
        int level_num = 1;
        
        while( !q.empty() ){
            
            int new_level_num = 0;
            stack<int> level;
            
            for(int i = 0; i < level_num; i++){
                TreeNode* node = q.front();
                q.pop();
                level.push(node->val);

                if(node->left){
                    q.push(node->left);
                    new_level_num++;
                }
                if(node->right){
                    q.push(node->right);
                    new_level_num++;
                }
            }
            res.push_back( level.top() );
            level_num = new_level_num;
        }
        
        return res;
    }
};

之字树 Leetcode 103. Binary Tree Zigzag Level Order Traversal
需要两个辅助栈

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */

class Solution {
public:
    vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
        
        vector<vector<int>> res;
        if(root == NULL)
            return res;
        
        stack<TreeNode*> levels[2];
        int cur = 0;
        int next = 1;
        
        levels[cur].push(root);
        while( !levels[cur].empty() || !levels[next].empty() ){
            
            vector<int> temp;
            while( !levels[cur].empty() ){

                TreeNode* node = levels[cur].top();
                levels[cur].pop();
                temp.push_back(node->val);

                if(cur == 0){
                    if(node->left)
                        levels[next].push(node->left);
                    if(node->right)
                        levels[next].push(node->right);
                }
                else{
                    if(node->right)
                        levels[next].push(node->right);
                    if(node->left)
                        levels[next].push(node->left);
                }

            }
            
            res.push_back(temp);
            if( levels[cur].empty() ){
                    cur = 1 - cur;
                    next = 1- next;
            }

        }
    
        return res;
    }
};

ps:1.剑指offer上题目真的是太经典了,得把它读厚才行,很多东西不要想着一次就做得十全十美,这是不可能的,多读一遍自然会有多读一遍的感悟。
2.波波老师Leetcode题解,https://github.com/liuyubobobo/Play-Leetcode,真的写得灰常灰常棒,作为菜鸡也只能抄抄波波老师的。
最后送自己一句,加油鸭!!!

你可能感兴趣的:(Leetcode)