题目:

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 1:

/**
* 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> ret;
if (!root) return ret;
stack<TreeNode *> sta;
sta.push(root);
while ( !sta.empty() ){
TreeNode *tmp = sta.top();
sta.pop();
if ( tmp->left || tmp->right ){
TreeNode *l = tmp->left, *r = tmp->right;
tmp->left = tmp->right = NULL;
sta.push(tmp);
if (r) sta.push(r);
if (l) sta.push(l);
}
else{
ret.push_back(tmp->val);
}
}
return ret;
}
};

stack 2:

/**
* 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> ret;
stack<TreeNode *> sta;
TreeNode *curr = root;
while ( !sta.empty() || curr )
{
if (curr)
{
sta.push(curr);
curr = curr->left;
}
else
{
curr = sta.top();
if ( !curr->right )
{
ret.push_back(curr->val);
sta.pop();
curr = NULL;
}
else
{
curr = curr->right;
sta.top()->right = NULL;
}
}
}
return ret;
}
};

tips:

上述两个代码都是基于stack的操作完成的后序遍历二叉树。

个人更喜欢stack 1的风格,思路如下:

0. 先压root入栈

1. 栈顶元素出栈

2. 如果其左右都为空:则可以直接推入ret中

否则:先将这个节点的left和right保存下来;再将这个节点与其子分支剪断(right left都置为NULL);再按照tmp, right, left的顺序入栈。

循环1~2,直到栈空,则后序遍历完成

网上一些答案很多都是基于stack 2这种方法,维护一个当前指针curr。

这个思路就是一条道走到黑的思路(DFS深搜)

1. curr不为NULL,则一直沿着left的方向走,直到走到NULL

2. 只要curr为NULL,则一定是栈顶元素的left已经没有了(走到头了),则需要判断栈顶元素的right是否为NULL;

  如果为NULL,则证明栈顶元素的left和right都访问过了,栈顶元素的val可以推入ret;

  如果不为NULL,则证明其right还得遍历。这个时候,需要完成两件事情:

    a. curr向right走

    b. 栈顶元素的right置为空(标记再次访问栈顶元素,其right已经再curr= curr->right的带领下处理过了)

其实stack 2的思路跟stack 1类似,都是需要判断栈顶元素的left和right是否都NULL,再决定栈顶元素的val是否推入ret。

==========================================

stack1和2的方法都在遍历之后对原有的数据结构损坏了(这显然是不合理的),因此改写了如下的代码,不递归不损坏原有数据结构

/**
* 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> ret;
stack<TreeNode *> sta;
TreeNode *curr = root;
std::map<TreeNode *, bool> r_visited;
while ( !sta.empty() || curr )
{
if (curr)
{
sta.push(curr);
curr = curr->left;
}
else
{
curr = sta.top();
if ( !curr->right || r_visited.find(curr)!=r_visited.end()?r_visited[curr]:false )
{
ret.push_back(curr->val);
sta.pop();
curr = NULL;
}
else
{
curr = curr->right;
r_visited[sta.top()] = true;
}
}
}
return ret;
}
};

tips:

之前如果curr->right访问过了,就直接sta.top()->right=NULL了,显然破坏了原有的数据结构。

这里用一个hashmap来保存访问过TreeNode的right是否被访问了。多了一个hashmap,但保住了原有数据结构。

=======================================================

第二次过这道题,就看看非递归的写法。找到了下面的一个blog:http://noalgo.info/832.html

用类似先序遍历的代码,再做一次翻转,就得到了后续遍历的结果。

/**
* 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> ret;
stack<TreeNode*> sta;
if ( root ) sta.push(root);
while ( !sta.empty() )
{
TreeNode* tmp = sta.top();
sta.pop();
ret.push_back(tmp->val);
if ( tmp->left ) sta.push(tmp->left);
if ( tmp->right ) sta.push(tmp->right);
}
std::reverse(ret.begin(), ret.end());
return ret;
}
};

后续遍历的顺序是:left right mid

因此,只要按照 mid right left的顺序遍历一次 再做reverse就可以了。

这个思路很巧妙。

========================================

做了这道题 突然想到了二叉树最小公共祖先,搜了一下http://blog.csdn.net/luckyxiaoqiang/article/details/7518888

先大概过一遍,心里有数。

【Binary Tree Post order Traversal】cpp的更多相关文章

  1. 【Binary Tree Level Order Traversal】cpp

    题目: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to ri ...

  2. 2016.6.24——vector<vector<int>>【Binary Tree Level Order Traversal】

    Binary Tree Level Order Traversal 本题收获: 1.vector<vector<int>>的用法 vector<vector<int ...

  3. 【遍历二叉树】04二叉树的层次遍历【Binary Tree Level Order Traversal】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,返回他的层次遍历的 ...

  4. 【Binary Tree Level Order Traversal II 】cpp

    题目: Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from ...

  5. 【遍历二叉树】05二叉树的层次遍历II【Binary Tree Level Order Traversal II】

    就把vector改成用栈类存放层次遍历的一层的序列 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  6. 【Binary Tree Right Side View 】cpp

    题目: Given a binary tree, imagine yourself standing on the right side of it, return the values of the ...

  7. 【Binary Tree Maximum Path Sum】cpp

    题目: Given a binary tree, find the maximum path sum. The path may start and end at any node in the tr ...

  8. 【一天一道LeetCode】#107. Binary Tree Level Order Traversal II

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 来源: htt ...

  9. 【Leetcode】【Easy】Binary Tree Level Order Traversal II

    Given a binary tree, return the bottom-up level order traversal of its nodes' values. (ie, from left ...

随机推荐

  1. TCP/UDP详解

    转载:http://www.cnblogs.com/visily/archive/2013/03/15/2961190.html, 作者:望梅止渴 相关: HTTP协议详解  深入理解HTTP协议 T ...

  2. js的变量作用域 ,变量提升

    (function(){ a = 5; alert(window.a); var a = 10; alert(a); })(); 结果: undefined 10 代码等同于下面 var a = un ...

  3. Js/Ajax中发送HttpPost请求调用WebService

    1) WebService中的方法 [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(Confo ...

  4. Sublime Text 2 常用快捷键

    Sublime Text 2 常用的快捷键 (不包含插件快捷键) Ctrl+P 打开文件搜索框,可以直接输入文件名搜索,或者输入@funcName 可以直接到函数定义处,输入#key 可以直接查找,输 ...

  5. LVS+keepalived实现负载均衡

    背景:         随着你的网站业务量的增长你网站的服务器压力越来越大?需要负载均衡方案!商业的硬件如F5又太贵,你们又是创业型互联公司如何有效节约成本,节省不必要 的浪费?同时实现商业硬件一样的 ...

  6. WordPress 主题开发 - (六) 创建主题函数 待翻译

    We’ve got a file structure in place, now let’s start adding things to them! First, we’re going to ad ...

  7. 【转】MYISAM表批量压缩

    关于对MYISAM表的压缩,可以使用myisampack和myisamchk完成(myisampack完之后必须进行myisamchk才能使用压缩后的表,而且是只读的), 其详细地用法可以参考官方文档 ...

  8. Python os模块常用部分功能

    os.sep 可以取代操作系统特定的路径分割符. os.name字符串指示你正在使用的平台.比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'. os.getcw ...

  9. .NET开源工作流RoadFlow-系统布署中常见错误及处理方法

    1.未开启asp.net状态服务时会出现以下错误: 解决办法:开启ASP.NET STATE SERVICE服务 2.未开启应用程序池32位: 解决办法:启用32位

  10. hdu 5273 Dylans loves sequence

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5273 Dylans loves sequence Description Dylans is give ...