Skip to content
DSA complexity 9 min read

Analyzing Recursive Complexity (Recurrences)

Analyzing recursive code means writing a recurrence — an equation that expresses a function’s cost in terms of its cost on smaller inputs — and then solving it for Big-O. The three tools you need are: writing the recurrence, drawing a recursion tree to add up the work per level, and the Master Theorem as a shortcut for divide-and-conquer. This page builds all three gently.

Step 1: write the recurrence

For a recursive function, ask two questions: how much work does one call do outside its recursive calls, and how many recursive calls on what size? Write T(n) = (calls) · T(smaller) + (work per call).

Linear recursion that shrinks n by 1 and does O(1) work per call gives T(n) = T(n-1) + O(1), which unrolls to O(n):

long long factorial(int n) {
    if (n <= 1) return 1;        // base case
    return (long long)n * factorial(n - 1); // T(n) = T(n-1) + O(1)
}

There are n calls, each O(1), so the time is O(n). Space is O(n) too — the call stack holds n frames at its deepest.

Step 2: the recursion tree

A recursion tree draws every call as a node and sums the work level by level. It’s the most reliable way to handle branching recursion. Take naive Fibonacci, which makes two calls each step — T(n) = T(n-1) + T(n-2) + O(1):

long long fib(int n) {
    if (n < 2) return n;
    return fib(n - 1) + fib(n - 2); // two branches
}

The tree roughly doubles in width each level and is about n levels deep, so the total number of nodes is about 2ⁿ. That makes naive Fibonacci O(2ⁿ) — exponential and unusable beyond small n. Adding memoization caches each fib(k) once, collapsing it to O(n).

For beginners: “How many calls, and how much smaller each time?” answers most questions. One call, size n-1 → linear. Two calls, size n-1 → exponential. Two calls, size n/2 → that’s the divide-and-conquer case below.

Step 3: divide-and-conquer and the Master Theorem

Divide-and-conquer algorithms split the input into a pieces of size n/b and do O(n^d) work to combine. Their recurrence is:

T(n) = a · T(n / b) + O(n^d)

The Master Theorem reads off the answer by comparing d against log_b(a):

CaseConditionResult
1d < log_b(a)T(n) = O(n^(log_b a))
2d = log_b(a)T(n) = O(n^d · log n)
3d > log_b(a)T(n) = O(n^d)

The intuition: case 1 means the leaves dominate, case 3 means the top-level work dominates, and case 2 is the balanced tie where every level costs the same — so you pay O(n^d) across log n levels.

Applying it to merge sort

Merge sort splits in half (a = 2, b = 2) and merges in linear time (d = 1). Here log₂ 2 = 1 = d, so case 2: T(n) = O(n log n).

#include <vector>
using namespace std;

vector<int> mergeSort(vector<int> a) {
    if (a.size() <= 1) return a;
    int mid = a.size() / 2;
    vector<int> left(a.begin(), a.begin() + mid);
    vector<int> right(a.begin() + mid, a.end());
    left = mergeSort(left);    // T(n/2)
    right = mergeSort(right);  // T(n/2)
    vector<int> out;           // merge: O(n)
    int i = 0, j = 0;
    while (i < (int)left.size() && j < (int)right.size())
        out.push_back(left[i] <= right[j] ? left[i++] : right[j++]);
    while (i < (int)left.size()) out.push_back(left[i++]);
    while (j < (int)right.size()) out.push_back(right[j++]);
    return out;
}

Binary search is T(n) = T(n/2) + O(1) (a = 1, b = 2, d = 0). Here log₂ 1 = 0 = dcase 2O(log n).

Going deeper: The Master Theorem only fits the a·T(n/b) + O(n^d) shape. Recurrences like T(n) = T(n-1) + O(n) (which is O(n²), e.g. naive quicksort’s worst case) don’t divide by a constant factor — solve those with a recursion tree or by unrolling. Also remember space: recursion depth d costs O(d) stack even when the time is small.

Quick reference

RecurrenceBig-OExample
T(n) = T(n-1) + O(1)O(n)factorial
T(n) = T(n-1) + O(n)O(n²)quicksort worst case
T(n) = T(n/2) + O(1)O(log n)binary search
T(n) = 2T(n/2) + O(n)O(n log n)merge sort
T(n) = 2T(n-1) + O(1)O(2ⁿ)naive Fibonacci / subsets

Next steps

Compare your recurrence findings against the complexity cheat sheet, revisit time vs space complexity for the stack-space angle, and then test yourself with the complexity exercises.

Last updated June 25, 2026
Was this helpful?