題幹
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?
用循環做樹的後序遍歷。
數據結構
/**
* Definition for binary tree
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
解題思路
這個題的思路是用輔助棧來維護整個輸出序列。
先遍歷左子樹,壓棧,然後右子樹,壓棧,遇到葉子結點,出棧,直接添加到 vector中。並且將其置爲NULL防止重複訪問。
看棧頂結點,繼續做上述操作。
例子:
1
/ \
2 3
/ / \
4 6 7
\
5
1 2 4 進棧
5進棧->葉子結點,出棧
4->葉子結點,出棧
2->葉子結點,出棧
3 6進棧
6->葉子結點,出棧
7進棧
7->葉子結點,出棧
3->葉子結點,出棧
1->葉子結點,出棧
最後序列爲:
5426731
參考代碼
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
TreeNode *pre,*cur=root;
vector<int> postorder;
stack<TreeNode *>tree;
while(cur!=NULL){//將左子樹直接壓棧,這部分代碼其實可以刪減
tree.push(cur);
pre=cur;
cur=cur->left;
}
cur=pre;
while(!tree.empty()){//分情況討論,有左子樹
if (cur->left!=NULL){
tree.push(cur->left);
cur=cur->left;
continue;
}
else if (cur->left==NULL&&cur->right!=NULL){//沒有左子樹,有又子樹
tree.push(cur->right);
cur=cur->right;
continue;
}
else if (cur->left==NULL&&cur->right==NULL){//是葉子結點
postorder.push_back(cur->val);
pre=cur;
tree.pop();
if (tree.empty()) break;
cur=tree.top();
if (pre==cur->left)
cur->left=NULL;
else cur->right=NULL;
continue;
}
}
return postorder;
}
};
易錯點
循環跳出
1.處理完每個結點要continue跳出本次循環
2.如果中間出現了棧已經空了的話直接跳出處理。
感想
總體來說這個題挺簡單,但是代碼寫的比較複雜,應該可以簡潔一點。