相似題目:
二叉樹的前序遍歷: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;
}
};