Pular para o conteúdo principal
Data structures, algorithms, and the core CS foundations — plus an optional advanced track for expert topics.

Core Computer Science

Data structures, algorithms, and the core CS foundations — plus an optional advanced track for expert topics.

Master Theorem Visualizer

Merge Sort — T(n) = 2T(n/2) + Θ(n)

Passo 0 / 0
Speed 100ms
Step Progress 0 / 0
Tree Levels 0
log_b(a) —
Status Ready
Level
Active level
Θ result
Step Explanation

Pick a recurrence and watch the recursion tree expand, level by level.

—
Pseudocode
 

Recurrences & Solving Recurrence Relations

Intermediate (3/5) ~2-3 hours Recurrence relations Substitution method Recursion tree method Master Theorem Divide-and-conquer recurrences Prereqs: Recursion, Big-O Notation & Complexity Analysis
Quick Reference

Merge Sort

Merge Sort is a classic divide-and-conquer algorithm. It recursively splits the array into single-element sub-lists, then merges adjacent sorted lists back together in sorted order.

Difficulty: Intermediate (3/5) Stablesorting

Complexity

Best Time
O(n log n)
Average Time
O(n log n)
Worst Time
O(n log n)
Space
O(n)

When to Use

When guaranteed O(n log n) worst-case time complexity and stability are required, or when sorting linked lists and external files.

Pros

  • Guaranteed O(n log n) efficiency for Best, Average, and Worst cases
  • Stable sort: preserves relative ordering of equal items
  • Highly efficient for linked list data structures and external sorting

Cons

  • Requires O(n) additional space for buffer arrays during merging
  • Higher memory copy overhead compared to in-place sorting routines

History

Merge Sort was invented by John von Neumann in 1945, making it one of the oldest computer sorting algorithms still in widespread use today.

Recurrence Relations: Recursion, Described in Math

A recurrence relation defines a function in terms of its own value at smaller inputs. For algorithm analysis, recurrences model the runtime of recursive algorithms: T(n) is the cost of a problem of size n, expressed as the cost of its subproblems plus the work to split and recombine.

T(n) = a · T(n/b) + f(n)

  • a = number of subproblems
  • n/b = size of each subproblem
  • f(n) = cost of dividing and combining
  • base case — T(1) = O(1), the point where recursion stops

Three canonical recurrences: binary search T(n) = T(n/2) + O(1), merge sort T(n) = 2T(n/2) + O(n), naive Fibonacci T(n) = T(n-1) + T(n-2) + O(1). The recurrence is a complete — if compact — description of the algorithm’s cost structure; solving it yields the asymptotic class.

The Substitution Method: Guess and Verify

  1. Guess the asymptotic form — from intuition, a recursion tree, or a known pattern.
  2. Verify by induction: assume the bound holds for all smaller inputs, substitute it into the recurrence, and confirm it holds for n.

For T(n) = 2T(n/2) + n, guess T(n) = O(n log n). Induction hypothesis: T(n/2) = c(n/2) log(n/2). Then:

T(n) ≤ 2 · c(n/2) log(n/2) + n
     = c n log(n/2) + n
     = c n (log n − 1) + n
     = c n log n − c n + n ≤ c n log n    for c ≥ 1

The guess is proven. Substitution is the most general method — it works when the Master Theorem’s conditions don’t apply — but it needs a good guess, a valid induction hypothesis, and careful base cases.

The Recursion-Tree Method: Seeing the Cost

Draw the recurrence as a tree: the root costs f(n), each node branches into a children of size n/b. Sum the work at each level, then sum across levels down to the base case. For T(n) = 2T(n/2) + n:

          n                    ← level 0: one node, cost n
        /     \
      n/2     n/2              ← level 1: two nodes, total n
     /  \     /  \
   n/4  n/4  n/4  n/4          ← level 2: four nodes, total n
    ...          ...

Every level totals n, and there are log₂ n levels, so T(n) = Θ(n log n). Recursion trees shine when the work per level is irregular — they show exactly where the cost concentrates, which substitution hides.

The Master Theorem

For T(n) = aT(n/b) + f(n) with a ≥ 1, b > 1, the theorem compares f(n) with the critical exponent c* = log_b(a) — the cost implied by the branching structure alone:

  1. Case 1 (subproblem-dominated): if f(n) = O(n^(c* − ε)), the recursion itself dominates → T(n) = Θ(n^c*).
  2. Case 2 (balanced): if f(n) = Θ(n^c* · log^k n), work is spread evenly across levels → T(n) = Θ(n^c* · log^(k+1) n).
  3. Case 3 (combine-dominated): if f(n) = Ω(n^(c* + ε)) and a·f(n/b) ≤ c·f(n) for some c < 1, the combine step dominates → T(n) = Θ(f(n)).

Worked applications:

Recurrencelog_b(a)CaseSolution
T(n) = 2T(n/2) + nlog₂2 = 1Case 2, f(n) = nΘ(n log n)
T(n) = T(n/2) + 1log₂1 = 0Case 2, f(n) = 1Θ(log n)
T(n) = 4T(n/2) + nlog₂4 = 2Case 1, n = O(n²⁻ε)Θ(n²)
T(n) = T(n/2) + nlog₂1 = 0Case 3, n = Ω(n⁰⁺ε)Θ(n)
T(n) = 2T(n/2) + n²log₂2 = 1Case 3, n² = Ω(n¹⁺ε)Θ(n²)

Case 2 also covers f(n) = n^c* · log^k n; case 3 needs the regularity condition a·f(n/b) ≤ c·f(n) — verify it whenever f(n) is not a clean polynomial.

Common Recurrences, Mapped

RecurrenceAlgorithmBig-O
T(n) = T(n/2) + O(1)Binary searchO(log n)
T(n) = 2T(n/2) + O(n)Merge sort, heapsortO(n log n)
T(n) = 2T(n/2) + O(1)Tree traversal (visit, recurse)O(n)
T(n) = T(n-1) + O(1)Linear scan / tail recursionO(n)
T(n) = 2T(n-1) + O(1)Towers of HanoiO(2ⁿ)
T(n) = T(n-1) + T(n-2) + O(1)Naive FibonacciO(2ⁿ)
T(n) = T(n-1) + O(n)Quicksort worst caseO(n²)

Quicksort deserves special attention: with a bad pivot the recurrence degrades to T(n) = T(n-1) + O(n) — one subproblem of size n−1 plus O(n) partitioning — solving to O(n²). With random pivots the average behaves like merge sort’s recurrence and lands at O(n log n). Same algorithm, two recurrences, two classes.

Worked Example: Merge Sort, Step by Step

Solve T(n) = 2T(n/2) + n — the n is the cost of merging two sorted halves.

  1. Split: dividing in half is O(1) (an index computation); folded into the merge cost.
  2. Level cost: at depth k there are 2^k subproblems of size n/2^k; each merge costs n/2^k, so a level costs 2^k · n/2^k = n.
  3. Depth: log₂ n levels until subproblems hit size 1.
  4. Total: log₂ n levels × n per level = Θ(n log n).

The Master Theorem gives the same answer in one line (case 2). Use the recursion tree when you want to see where the cost goes; use the theorem when you want speed — they must agree.

Practice Trajectory

  1. Write recurrences for binary search, merge sort, and quicksort’s worst case; solve each with the Master Theorem where possible.
  2. Draw the recursion tree for T(n) = 3T(n/4) + n² and sum the level costs to the base case.
  3. Prove T(n) = T(n/2) + O(1) → O(log n) by substitution (induction).
  4. Find a recurrence the Master Theorem cannot solve (e.g. T(n) = T(n-1) + log n) and solve it by unrolling.
  5. Derive merge sort’s O(n log n) three ways — recursion tree, substitution, Master Theorem — and confirm all three agree.

When It’s the Right Tool

SituationTakeaway
Clean divide-and-conquer algorithmMaster Theorem for one-line solutions
Irregular work per levelDraw the recursion tree
Master Theorem conditions failUse substitution or unrolling
Quicksort analysisGive average Θ(n log n) and worst Θ(n²)
Interview answerState the recurrence, then its class