3.6.2Sorting & Searching

Merge sort — divide and conquer, O(n log n), stable, proof of correctness

1,977 words9 min readdifficulty · medium6 backlinks

WHAT is merge sort?

The genius is that the divide step does no comparisons at all — it's just mid = (lo+hi)/2. All the intelligence lives in merge, which walks two sorted lists with two pointers.


WHY does merging work? (The core sub-routine)

HOW merge works (pointers i, j):
A = [1, 4, 7]    i→
B = [2, 3, 9]    j→
out = []
cmp 1,2 → take 1   out=[1]
cmp 4,2 → take 2   out=[1,2]
cmp 4,3 → take 3   out=[1,2,3]
cmp 4,9 → take 4   out=[1,2,3,4]
cmp 7,9 → take 7   out=[1,2,3,4,7]
A empty → copy 9   out=[1,2,3,4,7,9]

The diagram

Figure — Merge sort — divide and conquer, O(n log n), stable, proof of correctness

HOW to write it (Python, derived from the definition)

def merge(A, B):
    i = j = 0
    out = []
    while i < len(A) and j < len(B):
        # <=  (not <) is what makes merge sort STABLE
        if A[i] <= B[j]:
            out.append(A[i]); i += 1
        else:
            out.append(B[j]); j += 1
    out.extend(A[i:])   # copy leftover
    out.extend(B[j:])
    return out
 
def merge_sort(a):
    if len(a) <= 1:            # base case: already sorted
        return a
    mid = len(a) // 2
    left  = merge_sort(a[:mid])
    right = merge_sort(a[mid:])
    return merge(left, right)

Derive the running time from scratch

Why this recurrence? Two subproblems of half the size (the 2T(n/2)) plus a linear-time merge (cn).

Solve by the recursion tree (HOW):

  • Level 00: 1 problem of size nn → work cncn.
  • Level 11: 2 problems of size n/2n/2 → work 2cn2=cn2\cdot c\frac{n}{2}=cn.
  • Level kk: 2k2^k problems of size n/2kn/2^k → work 2kcn2k=cn2^k\cdot c\frac{n}{2^k}=cn.

Every level does cncn work. How many levels? We halve until size 11: n2L=1    L=log2n.\frac{n}{2^L}=1 \;\Rightarrow\; L=\log_2 n. Total levels =log2n+1=\log_2 n + 1. Therefore T(n)=cn(log2n+1)=Θ(nlogn).T(n)=cn\,(\log_2 n + 1)=\boxed{\Theta(n\log n)}.


Proof of correctness (induction on nn)

Proof by strong induction on n=len(a)n=\text{len}(a).

  • Base case n1n\le 1: a list of 00 or 11 element is trivially sorted and is its own permutation. ✓

  • Inductive hypothesis (IH): assume merge_sort is correct for all lengths <n< n.

  • Inductive step: for length nn, we split into left (size n/2<n\lfloor n/2\rfloor < n) and right (size n/2<n\lceil n/2\rceil < n). By IH both recursive calls return sorted permutations of their halves.

    Now prove merge is correct (loop invariant):

    • Initialization: out=[] — vacuously true.
    • Maintenance: we append min(A[i],B[j])\min(A[i], B[j]), which is \ge everything in out (by invariant) and \le all remaining (since A,BA,B sorted). Sortedness and the bound are preserved.
    • Termination: one list empties; we copy the rest (already sorted and \ge all of out). So out is a sorted permutation of ABA\cup B. ✓

    Hence merge(left,right) returns a sorted permutation of aa. By induction the algorithm is correct for all nn. \blacksquare


Worked examples


Flashcards

What are the three steps of merge sort?
Divide (split in half), Conquer (recursively sort halves), Combine (merge sorted halves).
Why is merge O(n)O(n)?
Two-pointer walk touches each of the nn elements exactly once.
Write the merge sort recurrence.
T(n)=2T(n/2)+cn, T(1)=O(1)T(n)=2T(n/2)+cn,\ T(1)=O(1).
Why does the recurrence give Θ(nlogn)\Theta(n\log n)?
Each of log2n\log_2 n levels does cncn work; cnlog2ncn\cdot\log_2 n.
What is merge sort's best / average / worst time?
All Θ(nlogn)\Theta(n\log n) — structure is input-independent.
What is merge sort's space complexity?
Θ(n)\Theta(n) extra (not in-place).
Which comparison keeps merge sort stable, < or <=?
<= (prefer the left element on ties).
What is the merge loop invariant?
out is sorted and \le all remaining elements of both inputs.
How do you prove merge sort correct?
Strong induction on nn + merge loop invariant; base case size 1\le 1.
Why is merge sort NOT O(n2)O(n^2) like insertion sort?
Only logn\log n merge layers, each linear, vs nn passes of nn work.

Recall Feynman: explain to a 12-year-old

Imagine two friends each holding a sorted stack of numbered cards. To combine them into one sorted stack, you just keep comparing the top card of each stack and taking the smaller — super easy! Merge sort first keeps cutting one messy stack in half until each tiny stack has just one card (already "sorted"), then plays this easy combine-game over and over until the whole thing is sorted. Cutting is free; combining is the smart part.

Connections

  • Divide and Conquer — the general paradigm merge sort exemplifies.
  • Quick sort — also O(nlogn)O(n\log n) average but in-place and not stable; merge sort is the stable counterpart.
  • Master Theorem — solves T(n)=2T(n/2)+Θ(n)T(n)=2T(n/2)+\Theta(n) directly (Case 2 ⟹ nlognn\log n).
  • Big-O Notation — language for the complexity bounds here.
  • Stability of Sorting Algorithms — why preserving equal-key order matters.
  • Recursion and Induction — the proof technique used above.
  • External Sorting — merge sort underlies sorting data too big for RAM.

Concept Map

is a

divide

conquer

combine

base case

uses

smallest at a front

gives

recurrence

solves to

solves to

prefer left on ties

Merge sort

Divide and conquer

Split at mid, no comparisons

Recursively sort halves

Merge two sorted lists

Size le 1 already sorted

Two-pointer walk

Each element touched once

Merge cost Theta n

T n = 2T n/2 + n

O n log n

Stable sort

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, merge sort ka pura funda ek line mein hai: ek badi list ko sort karna mushkil hai, par do already-sorted list ko jodna (merge karna) bahut easy hai. Isliye hum list ko baar-baar aadha-aadha kaatte rehte hain jab tak har piece sirf 1 element ka na ho jaaye — aur size-1 list to khud-ba-khud sorted hoti hai. Phir un sorted tukdo ko wapas merge karke upar le aate hain.

Merge kaise hota hai? Do pointers lagao, dono sorted lists ke front pe. Sabse chhota element hamesha kisi ek list ke aage hi hoga (kyunki peeche wale to bade hain). Compare karo, chhota wala utha lo, us pointer ko aage badha do. Har element bas ek baar touch hota hai, isliye merge O(n) hai. Yahi "lefty wins ties" wala rule — jab dono equal ho to left wala pehle lo — merge sort ko stable banata hai.

Time complexity samjho recursion tree se: har level pe pura nn ka kaam hota hai (merge), aur list ko aadha karte-karte total log2n\log_2 n levels banti hain. Toh n×logn=Θ(nlogn)n \times \log n = \Theta(n\log n). Aur sabse mast baat — input chahe sorted ho ya ulta, structure same rehta hai, isliye best, worst, average sab nlognn\log n. Bas extra memory O(n)O(n) chahiye, in-place nahi hai.

Correctness ka proof induction se hota hai: size 1\le 1 base case sorted hai; phir maan lo chote sizes ke liye sahi hai, toh dono aadhe sorted aate hain, aur merge unhe sahi se jod deta hai (loop invariant se). Bas, exam mein yeh proof + recurrence likh do, full marks pakke.

Go deeper — visual, from zero

Test yourself — Sorting & Searching

Connections