Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Preorder = visit the Node first, then the Left subtree, then the Right subtree. Recursively it's three lines: visit, recurse left, recurse right. The iterative version uses a stack: push the root, then loop — pop and visit a node, push its RIGHT child first and its LEFT child second, so left is processed before right. Both are O(n) time; O(h) space. Preorder is the natural order for serializing or cloning a tree top-down.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you can produce preorder recursively and iteratively, and whether you get the stack push order right (right child before left).
Where candidates slip
In the iterative version, pushing the LEFT child before the right — which reverses the output so right subtrees come first.
How to stand out
Write the recursion instantly, then derive the stack version and explain WHY you push right before left (LIFO means the last pushed is popped first).
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachExplore the full treeCollapse the tree
How to read it:Preorder visits the node before either subtree — the top-down DFS.
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 2
Recursive Preorder — Node, Left, Right
1Hint 1Explore hintHide hint
Preorder means the node is processed before its subtrees. Where does the visit go relative to the two recursive calls?
2Hint 2Explore hintHide hint
Base case: a null node produces nothing → return.
3Hint 3Explore hintHide hint
For a real node: visit it, then recurse left, then recurse right. The visit is the very first action.
A · Core idea
Preorder is defined recursively: to traverse a node, visit it immediately, then fully traverse its left subtree, then its right subtree.
Visit-first is the defining move. The only difference between the three DFS traversals is where the visit sits among the two recursive calls. Putting it first — before recursing into either child — yields preorder, which always emits the root before anything below it.
Why top-down matters. Because a parent is always processed before its children, preorder is the order you want when each child's handling depends on the parent already existing: serializing a tree to a string, deep-copying it node by node, or writing an expression tree in prefix (Polish) notation. Reconstructing a tree from a preorder sequence is straightforward precisely because the root comes first.
Base case. A null pointer (the child of a leaf) has nothing to visit, so it returns and the recursion unwinds.
Not sorted on a BST. Unlike inorder, preorder on a BST is not sorted — it lists the root, then the entire smaller-than-root subtree, then the larger one. If you need sorted output, that's inorder.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
root = [4,2,5,1,3]How to read it:Visit order in parentheses: 4 first (root), then 2,1,3,5.
4 2 1 3 5C · Code with teaching comments
Reference implementation preview// Definition for a binary tree node. class Node { int data; Node left; Node right;Explore the full codeHide the full code
D · Why it works and complexityO(n) timeO(h) spaceOpen the invariant and proofExplore the proofHide the proof
Preorder = inorder with the visit moved to the front. All three traversals are the same three statements reordered; preorder puts the visit first, giving you the parent before its descendants.
ComplexityO(n) time, O(h) space — Each node is visited exactly once with O(1) work → O(n) time. Recursion depth equals tree height h → O(h) space (O(log n) balanced, O(n) skewed).
E · Edge cases and pitfalls6root = [1] — Visit 1, both children null → output '1'.Explore edge casesHide edge cases
Edge cases handled
root = [1]Visit 1, both children null → output '1'.Left-skewed chain 3→2→1Visit each node on the way down → '3 2 1'.Right-skewed chain 1→2→3Visit then go right repeatedly → '1 2 3'.
Pitfalls
- Visiting after recursing left — that's inorder, not preorder.
- Forgetting the null base case.
- Recursing right before left — swaps the subtree order.
Approach 2 of 2 · Optimal
Iterative Preorder — Explicit Stack
1Hint 1Explore hintHide hint
Use a stack seeded with the root. What do you do each iteration to emit the root before its children?
2Hint 2Explore hintHide hint
Pop a node and visit it immediately (root-first). Then push its children so the LEFT is processed next.
3Hint 3Explore hintHide hint
A stack is LIFO: push the RIGHT child first, then the LEFT, so the left pops out before the right.
A · Core idea
Preorder visits the root first, which maps cleanly onto a stack: pop a node, visit it, and schedule its children for later.
The push order is the whole trick. A stack is last-in-first-out, so whatever you push last is popped first. We want the left child handled before the right, so we push the right child first and the left child second. On the next iteration the left child is on top and gets popped, visited, and expanded before the right subtree is ever touched.
Why visit on pop. Unlike inorder, there's no waiting: the moment we pop a node we can emit it, because preorder owes the node before its subtrees. After emitting, we push its children and move on.
Guard against null children. Only push children that exist; pushing nulls would force an extra null check on pop. The loop ends when the stack is empty, meaning every node has been visited.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
root = [4,2,5,1,3]How to read it:Each pop visits a node and pushes right-then-left so left is handled next.
4 2 1 3 5C · Code with teaching comments
D · Why it works and complexityO(n) timeO(h) spaceOpen the invariant and proofExplore the proofHide the proof
LIFO reverses push order, so to get Left-before-Right you push Right-before-Left. Saying that out loud — 'stack is LIFO, so I push the child I want last' — signals you understand the data structure, not just the recipe.
ComplexityO(n) time, O(h) space — Each node is pushed once and popped once → O(n) time. The stack holds at most O(h) nodes (right children waiting along the current path) — up to O(n) for a degenerate tree.
E · Edge cases and pitfalls6root = [1] — Push 1, pop-visit 1, no children → '1'.Explore edge casesHide edge cases
Edge cases handled
root = [1]Push 1, pop-visit 1, no children → '1'.Left-skewed chain 3→2→1Each pop pushes only a left child → '3 2 1'.Right-skewed chain 1→2→3Each pop pushes only a right child → '1 2 3'.
Pitfalls
- Pushing left before right — reverses subtree order in the output.
- Pushing null children — forces an extra null check on every pop.
- Visiting on push instead of pop — works for preorder but breaks if you later adapt this skeleton; visit-on-pop is the standard form.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic void preorder(Node root) { if (root == null) return; Deque<Node> stack = new ArrayDeque<>(); stack.push(root); while (!stack.isEmpty()) {Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Wrong push order in the iterative version
A stack is LIFO. Pushing the left child first means the right child is on top and gets processed before the left — reversing the intended order.
Explore the code comparisonHide the code comparison
Wrong push order in the iterative version
A stack is LIFO. Pushing the left child first means the right child is on top and gets processed before the left — reversing the intended order.
Don't write this
if (node.left != null) stack.push(node.left);
if (node.right != null) stack.push(node.right); // right ends up on topWrite this instead
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left); // left ends up on top2Visiting after the left recursion (inorder by accident)
Preorder must emit the node before either subtree. Printing after recursing left produces inorder output instead.
Explore the code comparisonHide the code comparison
Visiting after the left recursion (inorder by accident)
Preorder must emit the node before either subtree. Printing after recursing left produces inorder output instead.
Don't write this
def preorder(root):
if root is None:
return
preorder(root.left)
print(root.data, end=' ') # too late -> inorder
preorder(root.right)Write this instead
def preorder(root):
if root is None:
return
print(root.data, end=' ') # first -> preorder
preorder(root.left)
preorder(root.right)Revise
Carry the pattern into the interview
Pattern to remember
Depth-first traversal in Node → Left → Right order
Code pattern to memorize
preorder(node):
if node is null: return
visit(node)
preorder(node.left)
preorder(node.right)Rules to remember
- 1Order is Node, Left, Right — the node is visited before either subtree.
- 2Iterative: push right child first, then left, so the left is popped and processed first.
- 3Preorder visits the root first, making it ideal for serialization, cloning, and copying top-down.
- 4The base case (null → return) stops the recursion at the bottom of each branch.
- 5Preorder of a BST is NOT sorted — only inorder gives sorted order.
Use this pattern when
- Serializing or deep-copying a tree (you need the root before its children)
- Building a prefix/Polish-notation representation of an expression tree
- Any traversal where the parent must be processed before its descendants
Choose another pattern when
- You need sorted BST output → inorder, not preorder
- You need children-before-parent (freeing nodes, postfix expressions) → postorder
- You need level-by-level output → BFS level order
Interview takeaway
Preorder is the 'top-down' DFS: process a node, then its subtrees. The recursion is just the inorder code with the visit moved to the front. The iterative version's push-right-then-left ordering is the detail interviewers probe.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternPreorder DFS (Node → Left → Right). One of three traversals differing only in visit position; preorder is top-down, emitting the root before its subtrees, which makes it the order for serialization and reconstruction. The iterative stack version hinges on pushing the right child before the left.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Tree: Inorder TraversalMove the visit BETWEEN the two recursions (Left, Node, Right); sorted on a BST.
- Tree: Postorder TraversalMove the visit AFTER both recursions (Left, Right, Node).
- Serialize and Deserialize Binary TreeComing soonPreorder with null markers makes serialization and rebuilding straightforward.
- Construct Binary Tree from Preorder and InorderThe first preorder element is always the root — that's why preorder is so useful for reconstruction.