Recursion tree

RoadmapsDSA

Overview

A recursion tree is a visual representation of branching recursive calls. The root represents the initial call, and children represent the subproblems spawned by that call.

It allows you to read the time complexity of an algorithm visually. By summing the total work done across all nodes at every level, you can determine if an algorithm is efficient (like merge sort) or explosively slow (like naive Fibonacci).

Why learn this

Aha moment

def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

Prediction: Calculating `fib(5)` seems small, so it should only take a few steps.

Common guess: It makes 5 recursive calls because n=5.

`fib(5)` actually creates 15 total calls. `fib(3)` is computed 2 separate times, and `fib(2)` is computed 3 times. The total work is the sum of ALL nodes in the tree, not just the depth!

Common mistakes

Recall questions

Understanding checks

Merge sort divides an array in two halves and takes O(n) time to combine them. Naive Fibonacci spawns two smaller calls and takes O(1) time to add them. Why is merge sort O(n log n) but Fibonacci O(2^n)?

Merge sort's tree is balanced: every level does O(n) total work, and there are log(n) levels. Fibonacci's tree is leaf-heavy: the number of nodes explodes exponentially because each node spawns two children but the input size only decrements by 1 or 2, creating massive overlapping subproblems.

A tree where the problem size is halved at each step stays shallow (log n depth) and balanced. A tree where the problem size is only decremented stays deep (n depth), causing exponential node explosion.

When writing a program to parse nested structures like HTML or mathematical formulas, multiple recursive functions call each other (e.g., `parseExpression` calls `parseTerm`, which might call `parseExpression` again). What does the resulting recursion tree represent?

The recursion tree implicitly builds the hierarchical structure of the parsed text.

This is a real-world engineering application known as mutual recursion. The shape of the call stack's recursion tree exactly mirrors the nested structure of the data being parsed.

Practice tasks

Draw the tree and count nodes

Sketch the recursion tree for the naive recursive function `fib(4)`, where `fib(n) = fib(n-1) + fib(n-2)`. How many times is `fib(2)` computed in total? What does this tell you about its time complexity?

Continue learning

Previous: The call stack

Return to DSA Roadmap