LeetCode Week9: Binary Tree Preorder/InOrder/PostOrder Traversal

因为直接一打开就用已有的模版写了LeetCode Week 10, 所以导致我之前的Week 9被覆盖了,gg==
这一周完成的题目主要是Tree部分的题目,这里选择3道经典的题来编写题解,分别是Binary Tree Preorder Traversal、Binary Tree Inorder Traversal、Binary Tree Postorder Traversal。

一、Binary Tree Preorder Traversal

题目

Given a binary tree, return the postorder traversal of its nodes’ values.

For example:
Given binary tree {1,#,2,3},

 1
  \
   2
  /    
 3

return [1,2,3].

Note: Recursive solution is trivial, could you do it iteratively?

我的分析

对于前序遍历,其本质是先进行根遍历,接着是左子树遍历,最后是右子树遍历,那么利用递归方式实现的话,先遍历根结点,再递归遍历完左子树,最后递归遍历右子树即可。

而对于非递归的实现,则要借助stack和vector的帮助,首先从根结点开始,将根结点放入queue和vector中(结点放入queue中,值放入vector中),并不断的将左子节点放入queue中,之后不断的从queue中取出顶部的结点,结点的值此时已经放入了vector中,只需要按上述步骤遍历其右子结点即可(tmp = queue.top(); tmp= tmp->right)。

代码

按照分析代码实现如下:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode *root) {
        stack<TreeNode *> rec;
        vector<int> res;
        TreeNode* tmp = root;
        while(tmp || !rec.empty()){
            while(tmp){
                rec.push(tmp);
                res.push_back(tmp->val);
                tmp = tmp->left; 
            }
            tmp = rec.top();
            rec.pop();
            tmp = tmp->right;
        }
        return res;
    }
};

递归形式如下:

class Solution {
public:
    vector<int> preorderTraversal(TreeNode *root) {
        vector<int>res;
        preorder(root,res);
        return res;
    }
    void preorder(TreeNode *root,vector<int> &res){
        if(!root) return;
        res.push_back(root->val);
        preorder(root->left,res);
        preorder(root->right,res);
    }
};

二、Binary Tree Inorder Traversal

题目

Given a binary tree, return the postorder traversal of its nodes’ values.

For example:
Given binary tree {1,#,2,3},

 1
  \
   2
  /    
 3

return [1,3,2].

Note: Recursive solution is trivial, could you do it iteratively?

我的分析

对于中序遍历,其本质是先进行左子树遍历,接着是根遍历,最后是右子树遍历,那么利用递归方式实现的话,先递归遍历完左子树,再遍历根结点,最后递归遍历右子树即可。

而对于非递归的实现,则要借助stack和vector的帮助,首先从根结点开始,将根结点放入queue中,并不断的将左子节点放入queue中。之后不断的从queue中取出顶部的结点,并将结点的值放入了vector中(这样就可以保证是先遍历了左子结点才遍历根结点),之后再遍历其右子结点即可(tmp = queue.top(); tmp= tmp->right)。

代码

按照分析代码实现如下:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        stack<TreeNode*> rec;
        vector<int> res;
        TreeNode *tmp = root;
        while(tmp || !rec.empty()){
            while(tmp){
                rec.push(tmp);
                tmp = tmp->left;
            }
            tmp = rec.top();rec.pop();
            res.push_back(tmp->val);
            tmp = tmp ->right;
        }
        return res;
    }
};

递归形式如下:

class Solution {
public:
    vector<int> inorderTraversal(TreeNode *root) {
        vector<int>res;
        inorder(root,res);
        return res;
    }
    void inorder(TreeNode *root,vector<int> &res){
        if(!root) return;
        inorder(root->left,res);
        res.push_back(root->val);
        inorder(root->right,res);
    }
};

三、Binary Tree Postorder Traversal

题目

Given a binary tree, return the postorder traversal of its nodes’ values.

For example:
Given binary tree {1,#,2,3},

 1
  \
   2
  /    
 3

return [3,2,1].

Note: Recursive solution is trivial, could you do it iteratively?

我的分析

对于后序遍历,其本质是先进行左子树遍历,接着是右子树遍历,最后是根遍历,那么利用递归方式实现的话,先遍历遍历完左子树,再递归遍历右子树,最后遍历根结点即可。

而对于非递归的实现,则要借助stack和vector的帮助,同时还需要一个vistited指针(存上一个遍历的结点)。

       1
     /   \
    2     3
   / \   / \
  4   5 6   7
  1. 首先从根结点开始,将根结点放入queue中,并不断的将左子节点放入queue中;
  2. 之后不断的从queue中取出顶部的结点(记为tmp),对于tmp,如果它的右子结点是空,或者右子结点已经被遍历,那么我们就把这个结点的值放入vector 中,然后继续遍历queue中的结点,如果右子结点不是空的,或者还为遍历,那么就要遍历右子结点;
  3. 对于判断右子结点是否遍历过,就利用了visited指针,假设现在遍历到结点2,发现其右子结点不为空且也不等于visited指针(此时visited为4),那么就先遍历其右子结点5,5的左右子结点均为空,所以visited = 5,那么倒回来遍历2的时候,发现其右子结点与visited相等,那么就可以遍历2了。

代码

按照分析代码实现如下:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode *root) {
        stack<TreeNode*> rec;
        TreeNode* tmp = root;
        TreeNode* visited = NULL;
        vector<int> result;
        while(tmp || !rec.empty()) {
            while(tmp){
                rec.push(tmp);
                tmp = tmp->left;
            }
            tmp = rec.top();
            if(tmp->right == NULL || tmp->right == visited){
                result.push_back(tmp->val);
                visited = tmp;
                rec.pop();
                tmp = NULL;
            }
            else tmp = tmp->right;
        }
        return result;
    }   
}; 

递归形式如下:

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> nodes;
        postorder(root, nodes);
        return nodes;
    }
    void postorder(TreeNode* root, vector<int>& nodes) {
        if (!root) return; 
            postorder(root -> left, nodes);
            postorder(root -> right, nodes);
            nodes.push_back(root -> val);
    }

};   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值