DSA · Binary trees
Four traversals, one recursion
Preorder, inorder and postorder are one walk with the print line moved to three places. Level order needs a queue.
Step through the recursion on a live tree →01 The idea
A traversal is a rule for the order you print
An array has one obvious order: left to right. A tree does not. From node 5 you can go left, or you can go right, and whichever you pick you still owe the other side a visit. A traversal is the fixed rule that settles that argument for every node in the tree.
Three of the four traversals are depth-first: they dive to the bottom of one branch before touching the next. Written as recursion they are built from the same three moves — deal with the left child, deal with the right child, print this node — and left is always dealt with before right. The only thing that changes between them is where the print sits relative to those two calls. Level order is the odd one out: it refuses to dive at all and reads the tree row by row, which recursion cannot do on its own.
02 Hand trace
Inorder, by hand, on a 7-node tree
This is the tree the whole lesson uses. Seven nodes, values under 10, and it happens to be a binary search tree — every value on the left of a node is smaller, every value on the right is larger.
5 <- root / \ 3 8 / \ / \ 1 4 7 9 <- leaves
Now run inorder on it: left, then this node, then right. Follow the output row as it fills. A dot means that slot has not been printed yet.
Look at the route your finger took, not the numbers: down the left as far as it goes, back up one, out to the right, back up again. Preorder and postorder take that exact same route. They print 5 first, or 5 last, instead of printing it in the middle — and that single difference is the whole of section 03.
03 The code
One function, three print positions — and a queue for the fourth
Write the depth-first walk once. Keep exactly one of the three print lines and delete the other two; you have chosen your traversal. Level order cannot be written this way, so it gets its own loop on the right.
Depth-first · the one recursion
function walk(node): if node is null: return # base case print node.value # 1 -> PREORDER walk(node.left) print node.value # 2 -> INORDER walk(node.right) print node.value # 3 -> POSTORDER
Level order · a queue, no recursion
function levelOrder(root): if root is null: return q = new queue holding root while q is not empty: node = q.removeFirst() print node.value if node.left: q.add(node.left) if node.right: q.add(node.right)
Why one function and not three. The route is identical in all three orders, so three separate functions would duplicate the same two recursive calls and hide the only real difference. In an interview you want to answer "where does the print go?" in one sentence, and this shape is that sentence.
Why the null check is line 2 and not inside the caller. Node 1 is a leaf, but it still calls walk on two null children. Checking inside the callee means you write the guard once instead of at all three call sites — the two recursive calls and the first call on the root. It also explains the call count: our 7-node tree makes 15 calls, not 7.
Why level order needs a queue, not recursion. Recursion is a stack — last in, first out — so it always dives deeper before it comes back. Level order needs the opposite: finish row one completely before touching row two. A queue is first in, first out, which is exactly that promise.
Why the print line moves but walk(node.left) never does. Left is always taken before right in all four traversals. Swap those two lines instead of moving the print and you get the three mirror-image traversals, which is a standard follow-up question.
| Traversal | Rule | Output on our tree |
|---|---|---|
| Preorder | node, left, right | 5 3 1 4 8 7 9 |
| Inorder | left, node, right | 1 3 4 5 7 8 9 |
| Postorder | left, right, node | 1 4 3 7 9 8 5 |
| Level order | row by row, using a queue | 5 3 8 1 4 7 9 |
05 Cheat sheet
The numbers you will be asked for
| Question | Answer | Why |
|---|---|---|
| Time, any of the four | O(n) | Every node is entered exactly once and does constant work besides recursing. |
| Calls made by a DFS walk | 2n + 1 | n real nodes plus the n+1 null links. Our 7-node tree makes 15 calls. |
| Extra space, recursive DFS | O(h) | h is the height. The call stack holds one frame per level, not per node. |
| Extra space, skewed tree | O(n) | A tree with one child per node is a linked list, so h equals n. |
| Extra space, level order | O(w) | w is the widest level. In a perfect tree — every level completely filled — the bottom row alone is about n/2 nodes. |
| Inorder of a BST | sorted | Left values are all smaller and right values all larger, so they come out ascending. |
06 Where & why
Choosing an order is never about speed
All four traversals visit every node once and cost O(n). Picking between them is a question about timing: do you need a node's value before its children have been handled, after, or does only its distance from the root matter?
Reach for each one when…
Use something else when…
| Situation | Better choice | Why |
|---|---|---|
| The tree is deep and skewed — 100,000 nodes in a chain | Iterative DFS with your own stack | Recursion runs out of stack frames after a few thousand levels. An explicit stack lives on the heap and just grows. |
| You need the shortest root-to-leaf path | Level order (BFS) | BFS meets nodes in increasing depth, so the first leaf it reaches is the shallowest. DFS may dive down a long branch first and find it last. |
| You need inorder with no stack and no recursion | Morris traversal | It points the rightmost node of a left subtree — whose right pointer is null anyway — at its inorder successor, giving O(1) extra space at the cost of briefly rewiring the tree. |
| The structure is a graph, not a tree | DFS or BFS with a visited set | A tree has no cycles and no shared children, so a traversal can never revisit a node. Remove that guarantee and this exact code re-walks the same nodes — and on a cycle it never stops at all. |
07 Interview questions
What actually gets asked
Read the question, answer it out loud, then open the card. Each answer is about twenty seconds spoken.
What is a tree traversal?
What is the difference between preorder, inorder and postorder?
What is the time complexity, and why?
How much extra space does a recursive traversal use?
Why does inorder on a binary search tree come out sorted?
How many function calls does a DFS traversal of a 7-node tree make?
DFS or BFS on a tree — when do you pick which?
Can you do level order without a queue?
Given the preorder and inorder output, can you rebuild the tree?
How would you traverse a tree that is 100,000 nodes deep?
Where have you actually used a traversal outside an interview?
08 Practice problems
Six problems, in order of bite
Every one is solvable with the code from section 03 — the recursive walk for five of them, the queue loop for the level-order one. Check your answers against the lesson tree: 5 3 8 1 4 7 9 in level order.