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) {}
* };
*/
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
stack<TreeNode*> s;
stack<int> flag;
TreeNode* pNode = root;
while(<span style="background-color: rgb(255, 255, 51);">pNode != NULL ||</span> !s.empty()) {
while(pNode != NULL) {
s.push(pNode);
flag.push(0);
pNode = pNode->left;
}
if(!s.empty()) {
pNode = s.top();
if(flag.top() == 0) {
flag.pop();
flag.push(1);
<span style="background-color: rgb(255, 255, 102);">pNode = pNode->right;</span>
} else {
res.push_back(pNode->val);
flag.pop();
s.pop();
<span style="background-color: rgb(255, 255, 102);"> pNode = NULL;</span>
}
}
}
return res;
}
};
方法二:
仅仅需要一个栈:
首先把根节点压栈,然后循环如下操作:用一个变量来记录上次访问的节点,如果当前栈顶元素左右儿子都为空 或者 上次访问的节点非空且等于栈顶节点的左儿子或右儿子(如果左右孩子都有,则肯定先访问右孩子,等于做孩子是说明没有右孩子),则直接访问;否则把栈顶元素的右节点和左节点依次压栈。代码如下:
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> res;
if(root == NULL)
return res;
stack<TreeNode*> s;
TreeNode* pre = NULL;
TreeNode* pNode = root;
s.push(pNode);
while(!s.empty()) {
pNode = s.top();
if(pNode->left == NULL && pNode->right == NULL ||
(pre != NULL && (pre == pNode->left || pre == pNode->right))) {
res.push_back(pNode->val);
s.pop();
pre = pNode;
} else {
if(pNode->right != NULL)
s.push(pNode->right);
if(pNode->left != NULL)
s.push(pNode->left);
}
}
return res;
}
};