1. Recursive
Straight Forward, left -> right -> root
/** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int val) { * this.val = val; * this.left = this.right = null; * } * } */ public class Solution { /** * @param root: The root of binary tree. * @return: Postorder in ArrayList which contains node values. */ public ArrayList<Integer> postorderTraversal(TreeNode root) { // write your code here ArrayList<Integer> rst = new ArrayList<Integer>(); if (root == null) { return rst; } traversal(rst, root); return rst; } private void traversal(ArrayList<Integer> rst, TreeNode root) { if (root == null) { return; } traversal(rst, root.left); traversal(rst, root.right); rst.add(root.val); } }
2. Iterator
This is a little bit hard to understand, here is good reference https://sites.google.com/site/jennyshelloworld/company-blog/chapter-3---binary-tree-divide-conquer
The key to iterative postorder traversal is the following:
- The order of "Postorder" is: left child -> right child -> parent node.
- Find the relation between the previously visited node and the current node
- Use a stack to track nodes
As we go down the tree, check the previously visited node. If it is the parent of the current node, we should add current node to stack. When there is no children for current node, pop it from stack. Then the previous node become to be under the current node for next loop.
我们使用prev变量跟踪上一次访问的节点。假设栈顶元素是curr。当prev是curr的父节点时,我们正在向下遍历树。此时,优先遍历curr的左孩子(将左孩子压入栈)。如果没有左孩子,再看右孩子。如果左右孩子都不存在(curr是叶节点),就输出curr的值并弹出栈顶元素。
如果prev是curr的左孩子,我们正在从左子树向上遍历。我们看一下curr的右孩子。如果可以,就从右孩子向下遍历(将右孩子压入栈),否则打印curr的值并弹出栈顶元素。
如果prev是curr的右孩子,我们正在从右子树向上遍历。打印curr的值并弹出栈顶元素。
/** * Definition of TreeNode: * public class TreeNode { * public int val; * public TreeNode left, right; * public TreeNode(int val) { * this.val = val; * this.left = this.right = null; * } * } */ public class Solution { /** * @param root: The root of binary tree. * @return: Postorder in ArrayList which contains node values. */ public ArrayList<Integer> postorderTraversal(TreeNode root) { // write your code here ArrayList<Integer> rst = new ArrayList<Integer>(); Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode cur = root; TreeNode prev = null; if (root == null) { return rst; } stack.push(cur); while (!stack.empty()) { cur = stack.peek(); if (prev == null || prev.left == cur || prev.right == cur) { if (cur.left != null) { stack.push(cur.left); } else if (cur.right != null) { // 'else if' make sure all the left child will be processed first stack.push(cur.right); } } else if (cur.left == prev) { if (cur.right != null) { stack.push(cur.right); } } else { rst.add(cur.val); stack.pop(); } prev = cur; } return rst; } }
补充:
另一种方法; 后续遍历最后的结果是"左 => 右 => 中", 如果我们能得到一个stack的结果是”中=>右=>左“,那么我们把这个结果反过来就行了。而这个stack和前序遍历很像,只要把前序遍历左右顺序对调就行了
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: A Tree @return: Postorder in ArrayList which contains node values. """ def postorderTraversal(self, root): # write your code here if root is None: return [] post_order = [] stack = [root] node = root while stack: node = stack.pop() post_order.append(node.val) if node.left is not None: stack.append(node.left) if node.right is not None: stack.append(node.right) return post_order[::-1]
用python来写java的逻辑:
""" Definition of TreeNode: class TreeNode: def __init__(self, val): self.val = val self.left, self.right = None, None """ class Solution: """ @param root: A Tree @return: Postorder in ArrayList which contains node values. """ def postorderTraversal(self, root): # write your code here if root is None: return [] post_order = [] stack = [] node = root while node or stack: #如果能够向左就一直像左,不能就向右一步 while node is not None: stack.append(node) node = node.left if node.left is not None \ else node.right node = stack.pop() post_order.append(node.val) #如果处理过左节点,那么node就指向右节点 if stack and stack[-1].left == node: node = stack[-1].right else: node = None return post_order