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]
.
非递归版本:
我们需要维护当前遍历的cur指针和前一个遍历的pre指针来追溯当前的情况(注意这里是遍历的指针,并不是真正按后序访问顺序的结点)。具体分为几种情况:
(1)如果pre的左孩子或者右孩子是cur,那么说明遍历在往下走,按访问顺序继续,即如果有左孩子,则是左孩子进栈,否则如果有右孩子,则是右孩子进栈,如果左右孩子都没有,则说明该结点是叶子,可以直接访问并把结点出栈了。
(2)如果反过来,cur的左孩子是pre,则说明已经在回溯往上走了,但是我们知道后序遍历要左右孩子走完才可以访问自己,所以这里如果有右孩子还需要把右孩子进栈,否则说明已经到自己了,可以访问并且出栈了。
(3)如果cur的右孩子是pre,那么说明左右孩子都访问结束了,可以轮到自己了,访问并且出栈即可。
这里是引用了http://www.2cto.com/kf/201403/288184.html的说明
/**
* Definition for binary tree
* 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 *> stk;
TreeNode *pre = NULL;
stk.push(root);
while(!stk.empty()){
TreeNode *cur = stk.top();
if( pre == NULL || pre->left == cur || pre->right == cur){
if( cur->left)
stk.push(cur->left);
else if( cur->right)
stk.push(cur->right);
else{
res.push_back(cur->val);
stk.pop();
}
}
else if( cur->left == pre && cur->right)
stk.push(cur->right);
else{
res.push_back( cur->val);
stk.pop();
}
pre = cur;
}
return res;
}
};
递归版本:
/**
* Definition for binary tree
* 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;
_core( res, root);
return res;
}
void _core( vector< int> &res, TreeNode *root){
if( root == NULL)
return;
_core( res, root->left);
_core( res, root->right);
res.push_back(root->val);
}
};