Tree Algorithms

How In-Order Traversal Works

In-order traversal visits the left subtree, then the node, then the right subtree. On a binary search tree that emits every value in ascending order, which is the property most BST work rests on.

40241136554859
Output so far

Nothing yet.

  • Not reached
  • On the stack
  • Current
  • Visited
Speed

Step 1 of 19

In-order walk over 7 values, 3 levels deep.

Counters

Visited
0/7
On the stack
0
Tree height
3
Nodes
7

Settings

How it was built

In-order

  1. 1stack = []; node = root
  2. 2while node or stack:
  3. 3 while node:
  4. 4 stack.push(node)
  5. 5 node = node.left
  6. 6 node = stack.pop()
  7. 7 visit(node)
  8. 8 node = node.right

What each walk is for

WalkWhat you getTimeExtra space
In-orderValues in sorted orderO(n)O(h)
Pre-orderRoot before children, for copying a treeO(n)O(h)
Post-orderChildren before root, for freeing or evaluatingO(n)O(h)
Level-orderShallowest nodes first, level by levelO(n)O(w)
SearchOne value, by comparing at each nodeO(h)O(1)

n is the number of values, h the height of the tree and w its widest level. Build the tree from sorted values and h grows all the way to n — that is what balancing prevents.

Complexity

BestAverageWorstExtra memory
O(n)O(n)O(n)O(h)

h is the tree's height: O(log n) balanced, O(n) for a tree built from sorted inserts. The space is the call stack, or the explicit stack that replaces it.

How in-order traversal works

In-order traversal recurses into the left child, visits the current node, then recurses into the right child. Applied to a binary search tree — where everything left of a node is smaller and everything right is larger — that ordering emits the values sorted, without any comparison being made during the walk. Sorting a BST is therefore free; the work was done at insertion time.

  1. If the node is empty, return.
  2. Traverse the left subtree in full.
  3. Visit the node — this is where the value is emitted.
  4. Traverse the right subtree in full.

Implementation

The same algorithm the visualiser is running, written to be read.

def in_order(node, visit):
    if node is None:
        return
    in_order(node.left, visit)
    visit(node.value)
    in_order(node.right, visit)


def in_order_iterative(root):
    """The same walk without recursion, for trees deep enough to overflow."""
    out, stack, node = [], [], root
    while stack or node:
        while node:
            stack.append(node)
            node = node.left
        node = stack.pop()
        out.append(node.value)
        node = node.right
    return out

When to use it

  • Use it whenever a BST needs to be read in order: range queries, sorted exports, or finding the k-th smallest value.
  • Use it to check that a tree really is a valid BST — the in-order sequence must be strictly increasing, and that is a cleaner test than comparing each node with its children.
  • Use an explicit stack rather than recursion for deep trees, where a degenerate shape would otherwise overflow the call stack.

Check yourself

If the animation made sense, these should too.

Why does in-order traversal of a BST come out sorted?

Because the BST invariant says everything in the left subtree is smaller than the node and everything in the right is larger. Visiting left, then node, then right emits those three groups in exactly that order, recursively - so the whole sequence is ascending.

How would you check that a tree really is a valid BST?

Walk it in order and confirm the sequence is strictly increasing. Comparing each node only with its immediate children is not enough: a node can be larger than its left child and still violate the invariant against a grandparent.

More tree algorithms