A recursive call on n does n units of work and calls itself twice on n/2. How much work is that in all? Add it up one level at a time.
Adding up a tree of work
T(n) = aT(n/2) + n for n = 16, level by level
The root: one call on n = 16 does 16 units of work outside its recursive calls, then makes 2 calls on n/2 = 8.
- levels
- 1
- work so far
- 16
- leaves
- 16
- grows like
- –
Describe this picture
A picture with no code. On the left, the recursion tree of T(n) = aT(n/2) + n for n = 16: each call is a circle with its size in it, and edges join each call to the calls it makes. On the right, level with each row of the tree, is a bar for that level’s total work, with its numbers beside it, such as “2 × 8 = 16”; on a phone only the total is written. The clip takes about 11 seconds, with a = 2. First the root, 16, appears, and its bar reads “1 × 16 = 16”. Then a level each beat: two calls of 8, four of 4, eight of 2 and sixteen of 1, the leaves, and every bar is the same length, 16. Last, “total 80” appears under the bars. Under the picture are one sentence on the current beat and the readouts “levels”, “work so far”, “leaves” and “grows like”, which ends at “n log n”. After the clip, the slider “Branches a” sets a from 1 to 4 and replays the tree. With a = 1 the tree is a single chain and the bars shrink, 16, 8, 4, 2, 1, total 31. With a = 3 there are 81 leaves and the bars grow, 16, 24, 36, 54, 81, total 211. With a = 4 the 256 leaves crowd into a solid row and the bars grow faster, 16, 32, 64, 128, 256, total 496. The bars are scaled so that each tree’s largest level fills the same length. The transport plays and pauses, steps one beat back or forward, and scrubs; a and a paused step are kept in the page address as recurrences.a and recurrences.step.
A cost in terms of smaller costs
A recursive function’s cost depends on the cost of its own calls. Write T(n) for the cost on an input of size n, and read the recurrence straight off the code. Merge sort sorts two halves and merges them in about n steps, so
Binary search does a constant amount of work and continues in one half: T(n) = T(n/2) + 1. Each also needs a base case, a constant cost for the smallest inputs, here T(1) = 1. A recurrence is solved when T(n) is written without T on the right, exactly or as a Θ bound.
The method
Recursion trees
Draw every call as a node, under the call that made it, and write in each node the work that call does outside its own recursive calls. For T(n) = aT(n/b) + f(n), the root does f(n); its a children do f(n/b) each; their a² children do f(n/b²) each; and so on until the size reaches 1, after levels of dividing by b. The cost is the sum of every node, and the easiest way to add the nodes is one level at a time.
Level k has calls of size . The tree’s leaves, at level , number
since both sides have the same logarithm to base b, .
For f(n) = n and b = 2, as in the clip, level k does . With n = 16:
| a | levels 0 to 4 | total | grows like |
|---|---|---|---|
| 1 | 16 8 4 2 1 | 31 | n |
| 2 | 16 16 16 16 16 | 80 | n log n |
| 3 | 16 24 36 54 81 | 211 | |
| 4 | 16 32 64 128 256 | 496 | n² |
The level sums form a geometric series with ratio a/2. When the ratio is below 1 the series is dominated by its first term, the root. When it is 1 every level counts the same, and there are log₂ n + 1 of them. When it is above 1 the last term dominates: the leaves. The totals are exactly , , and .
Substitution
A recursion tree suggests an answer; substitution proves it. Guess the form of the answer, then show by induction that it satisfies the recurrence. For merge sort with T(1) = 1 and n a power of 2, guess T(n) = n log₂ n + n. It holds at n = 1, since 1·0 + 1 = 1. If it holds at n/2, then
so it holds at n. At n = 16 it gives 80, the clip’s total. For a Θ bound the guess can carry unknown constants, T(n) ≤ c·n log₂ n, and the induction then shows which c works.
The master theorem
The three shapes of the clip are the three cases of the master theorem. Let a ≥ 1 and b > 1 be constants, and let
with d ≥ 0 a constant and T(n) constant for small n; n/b may be rounded up or down. Then
| case | the levels | T(n) |
|---|---|---|
| shrink: the root dominates | ||
| stay level: every level | ||
| grow: the leaves dominate |
Comparing a with is comparing with d: the exponent of the number of leaves against the exponent of the root’s work. Level k does , the same geometric series, with ratio .
The theorem also has a form for any f(n), not only powers of n. With : if for some ε > 0, then ; if , then ; and if for some ε > 0 and for some constant c < 1 and all large n, then .
What it does not cover
The theorem needs a problem divided by a constant factor into a fixed number of parts. The Tower of Hanoi makes its problem smaller by one, not by a factor: M(n) = 2M(n − 1) + 1, whose solution is 2ⁿ − 1, exponential. The tree is a full binary tree n levels deep, and its levels sum to 1, 2, 4, …, 2ⁿ⁻¹.
It also misses work that falls between the cases. For T(n) = 2T(n/2) + n log₂ n, f is larger than , but not by a power of n, so no case applies. The tree still works: level k does , and adding the levels k = 0 to L − 1, with L = log₂ n, gives nL(L + 1)/2. The n leaves add n more, one each, so exactly T(n) = nL(L + 1)/2 + n, which is .
Worked example
Binary search and fast powers. T(n) = T(n/2) + 1: a = 1, b = 2, d = 0, and b^d = 1 = a, the middle case: Θ(log n). Fast powers, which square and halve the exponent, have the same recurrence.
Merge sort. T(n) = 2T(n/2) + n: a = 2 = 2¹, the middle case again: Θ(n log n).
Three products instead of four. Multiplying polynomials by halves needs four half-size products, T(n) = 4T(n/2) + n, which is Θ(n²): no better than the double loop. The split that makes do with three gives T(n) = 3T(n/2) + n: a = 3 > 2, so , about . At n = 1,024 = 2¹⁰ the tree has 3¹⁰ = 59,049 leaves, each a product of two single coefficients, against 4¹⁰ = 1,048,576 with four products. More branches do not mean exponential time: three branches on half the size grow more slowly than n².
Not covered. The Tower of Hanoi’s M(n) = 2M(n − 1) + 1 = 2ⁿ − 1, solved by its tree, not by the theorem.
Two checks. What is T(n) = 2T(n/2) + n²? (Θ(n²): a = 2 < 2² = 4, so the root dominates.) How many leaves has the a = 3 tree at n = 16? (3⁴ = 81.)
Where it’s used
Analysing any divide-and-conquer algorithm: sorting, as in merge sort and quicksort’s best case; searching; and fast multiplication.
The FFT, whose recurrence is T(n) = 2T(n/2) + n, the merge sort recurrence, and so Θ(n log n): the FFT in the signal processing course.
Reference card
| Idea | Meaning |
|---|---|
| T(n) = aT(n/b) + f(n) | a calls on size n/b, plus f(n) work in the call |
| level k | calls of size |
| leaves | |
| , | : the root dominates |
| : every level alike | |
| : the leaves dominate | |
| substitution | guess the answer, prove it by induction |
| T(n) = 2T(n − 1) + 1 | not divided by a factor: 2ⁿ − 1, by its tree |