This chapter establishes a fundamental lower bound showing that no comparison-based sort can do better than Ω(n lg n) in the worst case, then presents three algorithms—counting sort, radix sort, and bucket sort—that bypass this barrier by exploiting properties of the input beyond pairwise comparisons. These linear-time sorts demonstrate that when additional assumptions about the data hold (integer keys in a known range, fixed-length digit representation, or uniform distribution), sorting can be achieved in Θ(n) time.
The chapter opens by proving that every comparison sort must perform at least Ω(n lg n) comparisons in the worst case. The argument proceeds via the decision-tree model:
Model any comparison sort on n elements as a binary decision tree.
Each leaf corresponds to a permutation of the input; a correct sort must have all n! permutations reachable.
A binary tree of height h has at most 2ʰ leaves, so n! ≤ 2ʰ.
Taking logarithms: h ≥ lg(n!) = Ω(n lg n) (using Stirling's approximation).
This establishes Theorem 8.1: any comparison sort requires Ω(n lg n) comparisons in the worst case.
Corollary 8.2: Merge sort and heapsort, which run in O(n lg n) worst-case time, are asymptotically optimal among comparison sorts.
Idea: Given n integers each in the range 0 to k, determine for every element x how many elements are ≤ x, then place x directly into its correct output position.
How it works (COUNTING-SORT(A, B, k)):