Binary Tree Postorder Traversal asks for the node values in postorder: every node comes after both of its subtrees. It is a classic warm-up for the iterative tree-traversal pattern — turning recursion into an explicit stack.
Problem. Given the root of a binary tree, return the values of its nodes in postorder
traversal — left subtree, then right subtree, then the node itself.
Example: the tree with root 1, children 2 and 3, where 2 has children 4 and 5 and 3 has
right child 6, gives postorder [4, 5, 2, 6, 3, 1].
The slow way first
The textbook solution is recursive: visit left, visit right, then record the node. That is clean and O(n), but it leans on the call stack, and interviewers often ask for an iterative version to see if you really understand traversal order.
The naive iterative attempt — mimic preorder with a stack — gives root → left → right, which is the wrong order. The question to ask: can I produce postorder by tweaking an order I already know how to do iteratively?
The idea: build it backwards, then reverse
Postorder is left → right → root. Read that backwards and you get root → right → left. That reversed order is just a modified preorder, and preorder is easy to do with a single stack.
So: do a preorder-style walk that visits root → right → left, but instead of appending each node, prepend it to the output. Prepending while walking in reverse order leaves the list in correct postorder.
The key insight: pushing left then right means the right child sits on top and is popped next, so we walk root → right → left — exactly the reverse of postorder.
Walk through it
Step through the animation. The pop pointer marks each node as it leaves the stack. We pop 1, then 3, then 6, then 2, 5, 4 — that is root → right → left. Each popped value is prepended to output, so by the end the list already reads [4, 5, 2, 6, 3, 1], the postorder answer.
Pseudocode
if root is empty: return []
stack = [root]
output = []
while stack is not empty:
node = stack.pop()
prepend node.value to output # insert at the front
if node has a left child: push left
if node has a right child: push right # right ends up on top, pops first
return outputThe Python solution
def postorder(root):
if root is None:
return []
stack, output = [root], []
while stack:
node = stack.pop()
output.insert(0, node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return output- We seed the stack with the root and an empty
outputlist. node = stack.pop()takes the most recently pushed node — a LIFO stack.output.insert(0, node.val)prepends the value; this is what reverses root→right→left into postorder.- We push
leftthenright, sorightis on top and processed next — giving the reversed order we want. - When the stack empties, every node has been visited after its subtrees, and
outputis the answer.
Complexity
| Case | Time | Notes |
|---|---|---|
| Time | O(n) (moderate) | each node pushed and popped once |
| Stack space | O(n) (moderate) | up to a full level of nodes |
O(n) (moderate)One caveat: output.insert(0, ...) is O(n) per call in Python because it shifts the list. A tidier version appends each value and reverses once at the end (output[::-1]), keeping the whole thing O(n).
When this pattern shows up
Whenever a recursive traversal is asked for iteratively, reach for an explicit stack. Preorder is the easy one; inorder and postorder are variations. The reverse-the-modified-preorder trick is the cleanest way to get postorder without tracking which child you already visited.
Push order matters. To pop the right child first you push left then right. Swap them and you get root → left → right, which reverses into the wrong order. When in doubt, trace a tiny tree by hand.
Practice
Using push-left-then-right and prepending each popped value, which node is popped second for the example tree (root 1, children 2 and 3)?
1. What order do we walk the tree to produce postorder by prepending?
2. Why do we push the left child before the right child?
3. Why does prepending each popped value give postorder?
4. What is the time complexity of this traversal?