The Sorting Lower Bound

Week 4, Wednesday

January 28, 2026

In the Tuesday video, we saw recurrence forms and their solutions:

Recurrence Solution
\(T(n) = T(n-1) + 1\) \(O(n)\)
\(T(n) = T(n/2) + 1\) \(O(\log n)\)
\(T(n) = 2T(n/2) + 1\) \(O(n)\)
\(T(n) = 2T(n/2) + n\) \(O(n \log n)\)
\(T(n) = T(n-1) + n\) \(O(n^2)\)

Today: How do we prove these solutions?

Two Methods of Speculating

  1. Expansion method: Unroll the recurrence, find the pattern

  2. Recursion tree method: Visualize as a tree, sum the work

  • This is more of a sketch than a certainty
  • covered in enough detail in Tuesday video

Both give the same asymptotic answer. Choose whichever works for you!

Method 1: Expansion

The Idea

Unroll the recurrence step by step until you see a pattern.

Then apply the pattern to the base case to terminate.

Example 1:

\(T(n) = T(n-1) + c\)

Example 2:

(assume \(n = 2^k\) for simplicity):

\(T(n) = T(n/2) + c\)

Example 3:

(assume \(n = 2^k\) for simplicity)::

\(T(n) = 2T(n/2) + 1\)

Speculation is not a proof!!

Claim: The running time of merge-sort on data of size \(n\) is \(T(n) = O(n\log n)\).

Proof: Prove that there is a constant \(c\) so that \(T(n) \leq cn\log n\) for sufficiently large \(n\).

\(T(n) = 2T(n/2) + n, n > 1\)

By IH, \(T(n)\leq 2\cdot c(n/2)T(\log n/2) + n\)

\(=cn\log n - cn + n\)

\(\leq cn\log n\) when ______

A Big Question about Sorting

Can We Do Better?

We’ve seen:

  • Insertion sort: \(O(n^2)\) (PEX1, HW1)
  • Selection sort: \(O(n^2)\)
  • Merge sort: \(O(n \log n)\)
  • csort: \(O(n)\) (HW1)

Question: Is \(O(n \log n)\) the best we can do?

Or is there some clever algorithm that sorts in \(O(n)\)?

The Surprising Answer

Theorem: Any comparison-based sorting algorithm requires \(\Omega(n \log n)\) comparisons in the worst case.

This means:

  • Merge sort is optimal
  • No comparison sort can do better
  • \(O(n \log n)\) is a fundamental barrier

Decision Trees

The Key Idea

Every comparison-based sort makes decisions by comparing pairs of elements:

if arr[i] < arr[j]:
    ...
else:
    ...

We can model the algorithm as a binary tree of decisions.

Example: Sorting 3 Elements

Suppose we want to sort \([v_1, v_2, v_3]\).

v₁ < v₂? v₂ < v₃? v₁ < v₃? [__, __, __] v₁ < v₃? [__, __, __] v₂ < v₃? [__, __, __] [__, __, __] [__, __, __] [__, __, __]

What the Tree Represents

  • Internal nodes: Comparisons
  • Edges: Answers (yes/no, or \(<\) / \(\geq\))
  • Leaves: sorted ordering of the elements
  • Height: running time of the algorithm

Note:

  • There must be a leaf (endpoint) for each ordering of the elements
  • the tree itself is an encoding of an algorithm

Counting Leaves

How many different rearrangements are possible for an \(n\) element list?

Each ordering needs its own leaf (otherwise we’d give the same answer for different inputs).

The decision tree must have at least ______ leaves!

A Question for Later

Whose answer we need now…

A decision tree of height \(h\) has at most _______ leaves?

The Lower Bound Proof

Connecting Height to Comparisons

Recall: The height of the decision tree is the maximum number of comparisons in the worst case.

If the tree has height \(h\), then:

  • At most \(2^h\) leaves
  • We need at least \(n!\) leaves

Therefore: \(2^h \geq n!\)

Taking logarithms: \(h \geq \log_2(n!)\)

But How Big is \(\log(n!)\)?

Claim: \(\log(n!) = \Omega(n\log n)\)

The Result

Observation: Any comparison-based sorting algorithm requires \(\Omega(n \log n)\) comparisons in the worst case.

Justification:

  1. Model the algorithm as a decision tree
  2. The tree needs at least \(n!\) leaves
  3. A tree with \(\geq n!\) leaves has height \(\geq \log_2(n!)\)
  4. \(\log_2(n!) = \Theta(n \log n)\)
  5. Therefore, worst-case comparisons \(\Omega(n \log n)\)

What This Means

Algorithm Worst Case Optimal?
Merge Sort \(O(n \log n)\) Yes!
Heap Sort \(O(n \log n)\) Yes!
Quick Sort \(O(n^2)\) No (but avg is optimal)
Insertion Sort \(O(n^2)\) No
Selection Sort \(O(n^2)\) No

Merge sort achieves the theoretical limit.

Breaking the Barrier?

A Loophole

The lower bound applies to comparison-based sorts.

What if we don’t compare elements?

Counting Sort: When Elements are Small Integers

Idea: If elements are integers in range \([0, k]\), count occurrences!

Counting Sort in Action

Running time: \(O(n + k)\)

If \(k = O(n)\), this is \(O(n)\)linear time!

The Catch

Counting sort requires:

  • Elements must be integers (or convertible to integers)
  • Range \(k\) must be known and reasonable
  • Uses \(O(k)\) extra space

Not a general-purpose sort—but incredibly useful when it applies!

Other Linear-Time Sorts

Algorithm Constraint Time
Counting Sort Integers in \([0, k]\) \(O(n + k)\)
Radix Sort Fixed-width integers \(O(d \cdot n)\)
Bucket Sort Uniformly distributed \(O(n)\) expected

All exploit extra structure in the input.

Python’s Timsort

Python’s built-in sorted() uses Timsort:

  • Hybrid of merge sort and insertion sort
  • Exploits “runs” of already-sorted data
  • \(O(n \log n)\) worst case
  • \(O(n)\) on nearly-sorted data
  • Stable

In practice: Just use sorted()!

Connection to This Course

Why This Matters

  1. Lower bounds tell us when to stop searching for better algorithms

  2. The decision tree model appears again in:

    • Week 8: Binary search trees
    • Week 8: Wordle decision trees
  3. Divide-and-conquer analysis (recurrences) applies to:

    • PA1: Closest pair
    • Later: Quick sort, binary search

Summary

What We Learned This Week

Monday: Merge Sort + Recurrence Forms

  • Designed merge sort, saw \(T(n) = 2T(n/2) + O(n)\)
  • Five recurrence patterns and their solutions
  • Matching algorithms to recurrences

Tuesday Video: Solving Recurrences

  • Expansion method with formal proofs
  • Recursion tree method
  • Proved merge sort is \(O(n \log n)\)

Wednesday: Lower Bounds

  • \(\Omega(n \log n)\) is optimal for comparison sorts
  • Decision tree argument
  • Non-comparison sorts can break the barrier

Looking Ahead

  • PA1: Due Feb 8 — apply divide-and-conquer to closest pair
  • EX1: This week — covers analysis, loop invariants
  • Next week: The dictionary trick — \(O(n^2) \to O(n)\) transformations

Questions?