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?
这道题是后序遍历二叉树,题目难度为Hard。二叉树遍历是数据结构中的基本问题,觉得太low的同学可以跳过。
递归版本比较简单,不再详细说明,具体代码:
class Solution {
void getPostData(TreeNode* root, vector<int>& ret) {
if(!root) return;
if(root->left) getPostData(root->left, ret);
if(root->right) getPostData(root->right, ret);
ret.push_back(root->val);
}
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ret;
getPostData(root, ret);
return ret;
}
};
下面介绍非递归的方法,后序遍历二叉树是一种深度优先的遍历方法,不用递归的话就需要用栈来存储遍历路径上的节点。从根节点开始,一直向左遍历,依次将经过的节点进栈,直到某节点(记为p)的左子树为空,接下来就可以去遍历p的右子树了,如果它的右子树不空且没有遍历过,跳到它的右子树继续上述循环,否则说明p的右子树已经遍历完成,就可以将p出栈进行遍历了,这样循环直至栈空即完成了二叉树的后序遍历。如何判断p的右子树有没有遍历过呢?这里需要记录上一个后续遍历完毕的节点(记为q),即它的左右子树和它自己都已经遍历过了,如果p的右子树为q或为空,表明p的左右子树均已经遍历完毕,可以遍历p自己了,此时将堆栈出栈,遍历p并将q更新为p,因为p已经后序遍历完毕,这样通过q即可判断p的右子树是否已经遍历过。具体代码:
class Solution {
public:
vector<int> postorderTraversal(TreeNode* root) {
vector<int> ret;
stack<TreeNode*> stk;
TreeNode* p = root;
TreeNode* q = NULL;
while(p || !stk.empty()) {
while(p) {
stk.push(p);
p = p->left;
}
p = stk.top();
if(p->right == NULL || p->right == q) {
q = p;
stk.pop();
ret.push_back(p->val);
p = NULL;
}
else {
p = p->right;
}
}
return ret;
}
};