Base case
An instance solved directly, without another call.
Algorithms · Design techniques
Recursion turns a problem into smaller copies of itself. The code may be short, but execution builds a concrete structure of calls, local variables and suspended results.
You do not need to imagine every call at once. Assume the function can solve a smaller instance, then use that result to build the current solution.
An instance solved directly, without another call.
Shrinks the problem and combines the returned result.
Every call must genuinely move toward the base case.
This mirrors mathematical induction: a base case, an assumption about a smaller problem and an inductive step.
Every suspended call occupies a frame. A frame stores parameters, local variables, the return location and space for the return value. The stack is LIFO: the most recent call is the first to finish.
The newest call is on top ↑
Choose an example and advance one operation at a time. The tree shows all calls; the stack shows only the active chain at that instant.
fact(n)if n ≤ 1 return 1return n · fact(n − 1)fib(n)if n ≤ 1 return nleft ← fib(n − 1)right ← fib(n − 2)return left + right0! = 1
n! = n · (n−1)! for n > 0
T(n) = T(n−1) + Θ(1) = Θ(n). One call for every value from n to 1.
Θ(n) simultaneous frames before unwinding begins.
For fact(5), descent builds 5 · fact(4), then 4 · fact(3), and so on. Multiplication only starts at the base case: 1, 2, 6, 24, 120.
F₀ = 0, F₁ = 1
Fₙ = Fₙ₋₁ + Fₙ₋₂
T(n) = T(n−1) + T(n−2) + Θ(1) = Θ(φⁿ), where φ ≈ 1.618.
Θ(n): the tree is large, but only one path is live on the stack at a time.
Fibonacci recomputes fib(3), fib(2) and the same base cases many times. A cache indexed by n turns every repeated subproblem into a constant-time lookup. Enable “Use memoization” in the lab: purple nodes finish by reading a known result.
time · Θ(n) stack
time · Θ(n) stack + cache
time · Θ(1) space
| Prefer recursion | Prefer iteration |
|---|---|
| The structure is naturally recursive: trees, directories, divide and conquer, backtracking. | Depth may be very large or depends on untrusted input. |
| The code directly mirrors a definition and remains easier to verify. | A compact repeated state exists, such as only two consecutive Fibonacci values. |
| Depth is logarithmic or otherwise controlled. | Call overhead and stack memory matter. |
Tail recursion is not an automatic fix: JavaScript and PHP do not generally guarantee elimination of recursive frames. If depth can be high, use a loop or an explicit stack.
f(n) calls f(n) or moves n away from the base case.