题目描述
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?
后序遍历二叉树,使用非递归的方法解题思路
后序遍历结点的访问顺序是:左儿子 -> 右儿子 -> 自己。那么一个结点需要两种情况下才能够输出:
第一,它已经是叶子结点;
第二,它不是叶子结点,但是它的儿子已经输出过。
那么基于此我们只需要记录一下当前输出的结点即可。对于一个新的结点,如果它不是叶子结点,儿子也没有访问,那么就需要将它的右儿子,左儿子压入。如果它满足输出条件,则输出它,并记录下当前输出结点。输出在stack为空时结束。
这里我们需要注意一下压栈顺序,需先将右儿子压入再将做儿子压入,因为这个压入顺序关系到判断条件和输出顺序。当非叶子节点输出时,它的判断条件是:
node.left==headNode || node.right==headNode
headNode记录的上次弹出栈的节点,node.left==headNode针对的是该节点无右儿子的情况,node.right==headNode则针对第该节点无左儿子或左儿子已经输出的情况;
代码
public ArrayList<Integer> postorderTraversal(TreeNode root) {
ArrayList<Integer> list = new ArrayList<Integer>();
if(root==null)
return list;
Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
TreeNode node = root;
TreeNode headNode = root;//用于记录循环过程中每次弹出的节点
while(!stack.isEmpty()){
node = stack.peek();
if((node.left==null&&node.right==null) || node.left==headNode || node.right==headNode){
list.add(node.val);
stack.pop();
headNode = node;
} else {
if(node.right!=null){
stack.push(node.right);
}
if(node.left!=null){
stack.push(node.left);
}
}
}
return list;
}