In the first post, I introduced how to use Morris iteration to implement postorder traversal of a given binary tree. However it is too complicate and not easy to code during an interview. Here, I introduce another two ways to do a postorder traversal iteratively.
The first method is to use two stacks.
- Push the root node to the first stack.
- Pop a node from the first stack, and push it to the second stack.
- Then push its left child followed by its right child to the first stack.
- Repeat step 2) and 3) until the first stack is empty.
- Once done, the second stack would have all the nodes ready to be traversed in post-order. Pop off the nodes from the second stack one by one and you’re done.
List<Integer> list = new ArrayList<Integer>();
public List<Integer> postorderTraversal(TreeNode root) {
if(root == null)
return list; // corner case when root is null
Stack<TreeNode> stack1 = new Stack<TreeNode>();
Stack<TreeNode> stack2 = new Stack<TreeNode>();
stack1.push(root);
while(stack1.size() != 0) {
TreeNode cur = stack1.pop();
if(cur.left != null)
stack1.push(cur.left);
if(cur.right != null)
stack1.push(cur.right);
stack2.push(cur);
}
while(stack2.size() != 0)
list.add(stack2.pop().val);
return list;
}
Another way is just use one stack, and use a node to record the prior visited node. According to the type of the current node(leaf, nonleaf with only left or right child, nonleaf with both children) to perform differently.
- Each time we pick the top of the stack and check
- if it is a leaf node, then print it
- if it is a node with only left child, if pre = left child, then we know we have finish visiting the left child, print it; otherwise, the left child has not been visited yet, we push the current node pack and push the left child into stack
- if it is a node with only right child, similar with the prior one
- if it is a node with both children
- if pre = left child, we know we finish the left child and we need to continue with right child, so push itself and right child into stack
- if pre = right child, we know we have finished both child, print it
- else we have not visited any child, we push itself and left child into stack
- Update the pre node when we print something out
public static void postorder(TreeNode root) {
if(root == null)
return ; // corner case when root is null
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode pre = null, cur = null;
stack.push(root);
while(stack.size() != 0) {
cur = stack.pop();
if(cur.left == null && cur.right == null) {
System.out.println(cur.val);
pre = cur;
}
else if(cur.left != null && cur.right == null) {
if(pre == cur.left) {
System.out.println(cur.val);
pre = cur;
}
else {
stack.push(cur);
stack.push(cur.left);
}
}
else if(cur.left == null && cur.right != null) {
if(pre == cur.right) {
System.out.println(cur.val);
pre = cur;
}
else {
stack.push(cur);
stack.push(cur.right);
}
}
else {
if(pre == cur.left) {
stack.push(cur);
stack.push(cur.right);
}
else if(pre == cur.right) {
System.out.println(cur.val);
pre = cur;
}
else {
stack.push(cur);
stack.push(cur.left);
}
}
}
}
My implementation is somehow redundant. Here is a better implementation but a little harder to understand.http://leetcode.com/2010/10/binary-tree-post-order-traversal.html
没有评论:
发表评论