https://leetcode.com/problems/binary-tree-postorder-traversal/
这道题不用递归的话思路还是挺复杂的,网上有用一个栈的,有用两个栈的,我这里写的是用一个栈的,就是一直有一个pre和current的指针,来记录上一个被加入到结果list或者被进入栈的节点。
当pre是current的父节点时,说明pre还没有处理过(postorder),此时就看current,如果current有子树,那么把current的左节点入栈,如果没有左节点,则右子树入栈,即current是下一个需要处理的节点。如果current此时没有左右节点了,说明current是叶子节点,则current是当前应该加入到rst链表中的节点。
如果pre是current的左子树的话,说明pre的值已经加入到rst中了,这是就看current是否有右子树,如果current有右子树,那么把current右节点入栈,即先处理current的右子树再处理current。
如果pre是current的右子树的话,说明pre的值已经加入到rst中了,说明current的左右子树都处理完了,此时就把current的值再加入到rst中就可以了。按这个顺序依次遍历知道栈变为空。
注意这里一定要先检查相应的几点是否为null再入栈,保证入栈的都不是空节点。
public List<Integer> postorderTraversal(TreeNode root){
List<Integer> rst = new LinkedList<Integer>();
if(root==null) return rst;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode pre = null;
stack.push(root);
while(!stack.isEmpty()){
TreeNode current = stack.peek();
if(pre==null || pre.left==current || pre.right==current){
if(current.left!=null){
stack.push(current.left);
}
else if(current.right!=null){
stack.push(current.right);
}
else{
stack.pop();
rst.add(current.val);
}
}
else if(current.left==pre){
if(current.right!=null){
stack.push(current.right);
}
else{
stack.pop();
rst.add(current.val);
}
}
else if(current.right==pre){
stack.pop();
rst.add(current.val);
}
pre = current;
}
return rst;
}
新增C++代码:
class Solution {
public:
vector<int> postorderTraversal(TreeNode *root) {
vector<int> rst;
TreeNode* pre = NULL;
TreeNode* current = NULL;
stack<TreeNode* > stk;
if(root!=NULL) stk.push(root);
while(!stk.empty()){
current = stk.top();
if(pre==NULL || pre->left==current || pre->right==current){
if(current->left!=NULL) stk.push(current->left);
else if(current->right!=NULL) stk.push(current->right);
else{
stk.pop();
rst.push_back(current->val);
}
}
else if(current->left==pre){
if(current->right!=NULL) stk.push(current->right);
else{
stk.pop();
rst.push_back(current->val);
}
}
else if(current->right==pre){
stk.pop();
rst.push_back(current->val);
}
pre = current;
}
return rst;
}
};