相似题目:
二叉树的前序遍历:http://blog.csdn.net/Arcome/article/details/53672912
二叉树的中序遍历:http://blog.csdn.net/arcome/article/details/53672748
二叉树的后序遍历:http://blog.csdn.net/Arcome/article/details/53740883
Problem
Given a binary tree, return the postorder traversal of its nodes' values.
Recursive solution is trivial, could you do it iteratively?
Example
Given binary tree {1,#,2,3},
1
\
2
/
3
return [3,2,1].
Algorithm
整理一下题意:给定一棵二叉树,要求返回其后序遍历的结果。
首先是熟悉的递归版后序遍历的方法。将访问节点的操作设置在左节点的递归和右节点的递归之后。
代码如下。
//递归版本,用时0ms
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> path;
postorder(path,root);
return path;
}
void postorder(vector<int>&path, TreeNode* root){
if(root==NULL) return;
postorder(path,root->left);
postorder(path,root->right);
path.push_back(root->val);
}
};
对于非递归的实现,需要使用栈。
有两种方法,第一种方法是利用后序遍历与前序遍历镜像对称的关系。
后序遍历的过程是左->右->中,而前序遍历的过程是中->左->右,二者恰好相反,于是后序遍历的结果恰好是前序遍历结果的逆序。因此只要先进行非递归地前序遍历,然后将得到的结果逆序,即是后序遍历的结果了。
代码如下。
//非递归版本1,用时0ms
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> path;
stack<TreeNode*> st;
if(root==NULL) return path;
st.push(root);
TreeNode* top;
while(!st.empty()){
top=st.top();
st.pop();
path.push_back(top->val);
if(top->left!=NULL) st.push(top->left);
if(top->right!=NULL) st.push(top->right);
}
reverse(path.begin(),path.end());
return path;
}
};
第二种方法是直接进行后序遍历,比较复杂。
利用栈,设置三个指针cur,last和top,分别表示当前访问到达的节点,最后访问到达的节点和栈顶节点。首先从根节点开始不断将左子节点压入栈中,并将cur指向左子,直到cur为NULL。
若cur为NULL,说明某节点的左子为空,那么看右子。令top指向栈顶,若top节点的右子非空且未访问过(last不指向右子),则设置cur为右子节点,即右子节点继续进入上面的不断压入左子的循环。
若右子为NULL,或者右子已被访问,则说明top节点是叶节点,或者其左子和右子均已加入路径,那么直接把top节点加入路径即可,并把最后访问的节点设置为top(last=top)。弹出top,此时栈顶指向了原top的父节点。于是又进入上面的循环。由于此部分未涉及cur,所以重新进入循环后,仍是直接跳进对新top右子的判断,及开始对新top的右子数重复上述操作。
代码如下。
//非递归版本2,用时3ms
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> path;
stack<TreeNode*> st;
if(root==NULL) return path;
TreeNode* cur=root;
TreeNode* last=NULL;
TreeNode* top=root;
while(cur!=NULL||!st.empty()){
if(cur!=NULL){
st.push(cur);
cur=cur->left;
}
else{
top=st.top();
if(top->right!=NULL&&last!=top->right){
cur=top->right;
}
else{
path.push_back(top->val);
last=top;
st.pop();
}
}
}
return path;
}
};