题目:

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. HTML 表单总结http://images2015.cnblogs.com/blog/1001203/201607/1001203-20160730200559841-2144892373.png

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  2. jquery之val()和attr("value")

    1.attr("value")=原来的默认值 ,而val()=用户改变的值.

  3. 【转】mysql字符串函数

    对于针对字符串位置的操作,第一个位置被标记为1(即:第一个字母索引为1). ASCII(str) 返回字符串str的 最左面字符的ASCII代码值.如果str是空字符串, 返回0.如果str是NULL ...

  4. iOS中使用子线程的完整方法

    http://www.cnblogs.com/ygm900/archive/2013/06/23/3151691.html 第一步:开启子线程 //开启子线程到网络上获取数据 myFirstThrea ...

  5. 10)Java Error and Exception

      1>异常继承类        Error类和Exception类都继续自Throwable类      Error表示系统级的错误情况,如内存错误这样程序无法通过自身的处理再继续执行下去的情 ...

  6. SQL Server 基础:拾遗

    1.一条完整的sql语句: select top | distinct 字段, 表达式, 函数, ... from 表表达式 where 筛选条件 group by 分组条件 having 筛选条件 ...

  7. Ksoap2 获取webservice返回值的getResponse() 出现的问题

    今天写了一个判断记录重复的webservcie 返回布尔类型 // 判断序列号在数据库是否重复 public static boolean isSerialNumExist(String serial ...

  8. masterha_check_repl报错汇总

    [root@DBMysql ~]#masterha_check_repl --conf=/etc/masterha/app1.cnf 导致如下报错的原因主要有两类: 1.mysql的安装时用源码安装, ...

  9. 从0 开始 WPF MVVM 企业级框架实现与说明 ---- 第二讲 WPF中 绑定

    说到WPF, 当然得从绑定说起,这也是WPF做的很成功的一个地方,这也是现在大家伙都在抛弃使用winform的其中一个主要原因,Binding这个东西从早说到完其实都说不完的,我先就做一些基本的介绍, ...

  10. 用Python作GIS之五:从示例入手—example函数

    进入STARS后,最简单的学习方法就是演示示例数据.对于源码的分析也可以从这里入手.        以下为出发菜单项“Example Project”的函数example:def example(se ...