Tree traversals
Preorder, inorder and postorder traversal of a binary tree with recursion; inorder on a search tree gives the keys sorted.
Traversing a tree means visiting every node exactly once. In a binary tree, each node has a left and a right subtree, so recursion is the natural way: to traverse a tree, visit the root and traverse the two subtrees the same way. The three classic traversals differ only in where the root is visited:
Read the full explanation ↓- Time:
O(n) - Space:
O(h) for the recursion (h = height) - Horowitz–Sahni, chapter 5
- CLRS, section 12.1
- Johnsonbaugh, chapter 9
- Grimaldi, chapter 12
An uneven seven-node search tree; the three traversals give three different orders, and inorder is sorted.
class Node:def __init__(self, key):self.key = keyself.left = Noneself.right = Nonedef traversals(root):pre = []preorder(root, pre)ino = []inorder(root, ino)post = []postorder(root, post)return pre, ino, postdef preorder(node, out):if node is None:returnout.append(node.key)preorder(node.left, out)preorder(node.right, out)def inorder(node, out):if node is None:returninorder(node.left, out)out.append(node.key)inorder(node.right, out)def postorder(node, out):if node is None:returnpostorder(node.left, out)postorder(node.right, out)out.append(node.key)
Start
Recursion tree
Filled orange = running call · Orange outline = still on the stack · Grey = finished
Local variables
Orange = changed in this step
root object
- key = 15
- left = Node(key=6, left=Node(key=3, left=None, right=None), right=Node(key=7, left=None, right=None))
- right = Node(key=18, left=Node(key=17, left=None, right=None), right=Node(key=20, left=None, right=None))
Call stack
- traversals()line 8
How the work grows with input size
Average of 8 random graphs per n (fixed seeds). Hollow marker = the input on screen.
- visit
- current input (n=7)
Show as a table
| n | visit |
|---|---|
| 3 | 9 |
| 5 | 15 |
| 7 | 21 |
| 9 | 27 |
| 11 | 33 |
| 13 | 39 |
| 15 | 45 |
Explanation
The idea
Traversing a tree means visiting every node exactly once. In a binary tree, each node has a left and a right subtree, so recursion is the natural way: to traverse a tree, visit the root and traverse the two subtrees the same way. The three classic traversals differ only in where the root is visited:
| Traversal | Order | | --- | --- | | Preorder | node, left, right | | Inorder | left, node, right | | Postorder | left, right, node |
The key fact: inorder on a search tree
In a binary search tree, every key in the left subtree is smaller and every key in the right subtree is larger. So an inorder traversal gives the keys in ascending order.
Uses
- Preorder: copying a tree, writing an expression in Polish notation.
- Postorder: deleting a tree, evaluating an expression tree, computing sizes or heights.
Cost
Every node is visited once: O(n). The recursion is as deep as the tree is high: log n for a balanced tree, n for
a chain.
What to watch in the trace
- The orange node is
nodein the running call, and black nodes have already been added to the output. - The
outlist under the tree shows the order of visits. - In the "recursion tree", the
∅calls are the missing children that return at once. - The "every loop round" detail level shows only the end of each of the three traversals.