LeetCode Week9: Binary Tree Preorder/InOrder/PostOrder Traversal

来源:互联网 发布:excel2016数据挖掘 编辑:程序博客网 时间:2024/05/16 00:56

因为直接一打开就用已有的模版写了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