题目:

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. 树莓派(Rospberry Pi B+)到货亲测

    1 图鉴 Rospberry Pi  B+终于在今天下午有蜗牛快递公司圆*送到了.B+主要是增加了2个USB,增加了GPIO,sd卡换成了micro sd ...先不说直接上图再说,期待了好久好久 整 ...

  2. 视频特效制作:如何给视频添加边框、水印、动画以及3D效果

    2014-12-08 09:47 编辑: suiling 分类:iOS开发 来源:叶孤城的blog 招聘信息: iOS手机软件开发工程师 iOS工程师 Web后端高级开发工程师 iOS软件工程师 ja ...

  3. asp.net中分页与存储过程的一些总结

    一.接上文,使用的是jquery AJAX 进行分页 分页存储过程代码如下: ALTER PROCEDURE [dbo].[USP_GetAlbumByPage] @pageIndex int,--当 ...

  4. silverlight 退出系统(关闭当前网页),通过调用JS

    确认后直接退出系统,关闭当前页面 页面部分: <HyperlinkButton x:Name="LinkExit" Style="{StaticResource L ...

  5. php不使用插件导出excel

    php不使用插件导出excel的简单方法,首先获取需要导出的数据的数组,数组的格式在下面. 之后就是定义文件名称和需要导出的excel的样式,最后就是循环数组,输出数据了 代码: $filename= ...

  6. S5PV2210

    http://www.doc88.com/p-773451739254.html CAN转换器 CAN总线信息转换输出装置 基于车载CAN总线的倒车雷达单元设计[图] http://www.doc88 ...

  7. 用VBA计算WPS 表格ET EXCEL中的行数和列数的多重方法

    用VBA计算WPS 表格ET EXCEL中的行数和列数 每种方法中上面的是Excel的行数,下面的是Excel的列数. 方法1: ActiveSheet.UsedRange.Rows.Count Ac ...

  8. PHP JS HTML ASP页面跳转代码 延时跳转代码 返回到上一界面并刷新 JS弹出指定大小的新窗口

    1.PHP延时跳转代码 //跳转到浏览界面 header("Refresh:1;url=machine_list.php"); //不延时 <?php header(&quo ...

  9. 4.html5中超链接

    html中超链接都是通过<a>标签实现的,html5也不例外,这里就来探讨一下<a>标签. <a>元素属于文本元素,有一些私有属性或者叫局部属性.那么,相对应的还有 ...

  10. NOJ1142-最大连续和

    最大连续和 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 1282            测试通过 : 230 ...