您的位置:首页 > 其它

Binary Tree Postorder Traversal

2016-02-24 22:14 302 查看
题目名称

145.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?

分析

  由后序遍历过程可知,采用一个栈保存需要返回的节点指针,先扫描根节点的所有左结点并一一进栈,出栈一个节点*b即当前节点,然后扫描该节点的右孩子节点并进栈,再扫描该右孩子结点的所有左结点并进栈。当一个节点的左右孩子结点均被访问后再访问该节点,如此这样,直到栈为空为止。

  其中的难点是如何判断一个节点*b的右孩子节点已被访问过,为此用p保存刚刚访问过的节点(初值为NULL),若b->right == p或者b->right==NULL,说明*b的左右子树均被访问过,现在应访问*b。

  从上述过程可知,栈中保存的是当前结点*b的所有祖先节点。对应的非递归算法如下:

C++代码

/**
* 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> res;
if(!root) return res;
stack<TreeNode *> st;
TreeNode *p,*b=root;
int flag = 0;
st.push(b);
while(!st.empty()) {
while(b->left) {
st.push(b->left);
b=b->left;
}
p=NULL;
flag = 1;
while(!st.empty() && flag) {
b = st.top();
if(b->right ==p || !b->right) {
res.push_back(b->right);
st.pop();
p=b;
}
else {
b=b->right;
st.push(b);
flag=0;
}
}
}
return res;
}
};


一个更好的算法

  算法是这道题的讨论里面得票数最多的,他的解释是这样的:

Create an empty stack, Push root node to the stack.

Do following while stack is not empty.

2.1. pop an item from the stack and print it.

2.2. push the left child of popped item to stack.

2.3. push the right child of popped item to stack.

reverse the ouput.

class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
stack<TreeNode*> nodeStack;
vector<int> result;
//base case
if(root==NULL)
return result;
nodeStack.push(root);
while(!nodeStack.empty())
{
TreeNode* node= nodeStack.top();
result.push_back(node->val);
nodeStack.pop();
if(node->left)
nodeStack.push(node->left);
if(node->right)
nodeStack.push(node->right);
}
reverse(result.begin(),result.end());
return result;

}
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息