Introduction

This note brings the sorting algorithms together. It proves that no comparison sort can beat Ω(nlg⁡n)\Omega(n \lg n) in the worst case (or on average), states the exact comparison counts for related problems (maximum, minimum and maximum, second largest, merging), and compares all standard sorts on time, space, stability and adaptivity. It is the reference page to use when a question asks "which sort" or "which statement is true".

Prerequisites

The decision-tree model

A comparison sort gains information about the input only by comparing pairs of keys (ai≤aja_i \le a_j?). Its behaviour on all inputs of size nn can be drawn as a decision tree:

  • each internal node is a comparison ai:aja_i : a_j, with one subtree for each outcome;
  • each leaf is a permutation π\pi, meaning "the sorted order is aπ(1)≤aπ(2)≤⋯≤aπ(n)a_{\pi(1)} \le a_{\pi(2)} \le \dots \le a_{\pi(n)}";
  • one execution follows one root-to-leaf path; its number of comparisons is the length of that path.

The model counts only comparisons and ignores all other work, so a lower bound on comparisons is a lower bound on time.

Decision tree of insertion sort on three elements
Figure 1. The decision tree of insertion sort on a1,a2,a3a_1, a_2, a_3: the root compares a1:a2a_1 : a_2, internal nodes compare the key being inserted with earlier ones, and the six leaves are the six orderings; two leaves are at depth 2 and four at depth 3.

The lower bound

Theorem (CLRS 3e, Theorem 8.1). Any comparison sort algorithm requires Ω(nlg⁡n)\Omega(n \lg n) comparisons in the worst case.

Proof. The algorithm must be correct for each of the n!n! orderings of nn distinct keys, and different orderings need different leaves, so the tree has at least n!n! reachable leaves. A binary tree of height hh has at most 2h2^h leaves. Therefore 2h≥n!2^h \ge n!, so

h  ≥  lg⁡(n!)  =  Θ(nlg⁡n),h \;\ge\; \lg(n!) \;=\; \Theta(n \lg n),

where lg⁡(n!)=Θ(nlg⁡n)\lg(n!) = \Theta(n \lg n) follows from Stirling's approximation (or from lg⁡(n!)≥lg⁡((n/2)n/2)=n2lg⁡n2\lg(n!) \ge \lg\big((n/2)^{n/2}\big) = \tfrac{n}{2}\lg\tfrac{n}{2}).

Consequences:

  • Merge sort and heapsort, with O(nlg⁡n)O(n \lg n) worst-case comparisons, are asymptotically optimal comparison sorts.
  • The exact bound ⌈lg⁡(n!)⌉\lceil \lg(n!) \rceil is 1 for n=2n = 2, 3 for n=3n = 3, 5 for n=4n = 4, 7 for n=5n = 5 and 10 for n=6n = 6. For these small nn it is achieved, so it is the minimum worst-case number of comparisons. In general it is only a lower bound: no theorem says some algorithm meets it for every nn.
  • The best case is at least n−1n - 1. Every leaf of a correct decision tree is at depth at least n−1n - 1. Think of each comparison as an edge between two keys: if the edges seen on a path do not connect all nn keys, two of the resulting groups have never been compared, and the algorithm cannot know their relative order. Insertion sort on sorted input meets this with exactly n−1n - 1 comparisons; in Figure 1 the shortest paths have length 2=n−12 = n - 1.
  • Nearly sorted input. For 1≤k≤n−11\le k\le n-1, if every key is at most kk positions from its sorted place, a min-heap of the next at most k+1k+1 keys sorts in O(nlg⁡(k+1))O(n\lg(k+1)) time. For a lower bound, permute keys independently inside q=⌊n/(k+1)⌋q=\lfloor n/(k+1)\rfloor full blocks of k+1k+1 consecutive sorted ranks, leaving the remaining keys fixed. All ((k+1)!)q((k+1)!)^q permutations satisfy the displacement limit, requiring at least ⌈qlg⁡((k+1)!)⌉\lceil q\lg((k+1)!)\rceil worst-case comparisons, which is Ω(nlg⁡(k+1))\Omega(n\lg(k+1)). For k=0k=0, the input is already sorted; reading or outputting it takes Θ(n)\Theta(n), and no comparison lower bound of that order is implied.
  • Average case too. The average depth of the n!n! leaves of any binary tree is at least lg⁡(n!)\lg(n!), so the average number of comparisons, over uniformly random orderings, is also Ω(nlg⁡n)\Omega(n \lg n). Quicksort's Θ(nlg⁡n)\Theta(n \lg n) average is therefore optimal in order.
  • The bound applies only to comparison sorts. Counting, radix and bucket sort avoid it by using key values as indices.

The comparison table

nn = number of keys; kk = key range; dd = number of digits; II = number of inversions. Space is auxiliary space.

AlgorithmBestAverageWorstSpaceStableIn placeAdaptive
Bubble sort (with flag)Θ(n)\Theta(n)Θ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)O(1)O(1)yesyesyes
Selection sortΘ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)O(1)O(1)noyesno
Insertion sortΘ(n)\Theta(n)Θ(n2)\Theta(n^2)Θ(n2)\Theta(n^2)O(1)O(1)yesyesyes, Θ(n+I)\Theta(n + I)
Merge sortΘ(nlg⁡n)\Theta(n \lg n)Θ(nlg⁡n)\Theta(n \lg n)Θ(nlg⁡n)\Theta(n \lg n)Θ(n)\Theta(n)yesnono (natural variant: yes)
QuicksortΘ(nlg⁡n)\Theta(n \lg n)Θ(nlg⁡n)\Theta(n \lg n)Θ(n2)\Theta(n^2)Θ(lg⁡n)\Theta(\lg n) to Θ(n)\Theta(n) stacknoyesno
HeapsortΘ(nlg⁡n)\Theta(n \lg n) (distinct keys)Θ(nlg⁡n)\Theta(n \lg n)Θ(nlg⁡n)\Theta(n \lg n)O(1)O(1)noyesno
Counting sortΘ(n+k)\Theta(n + k)Θ(n+k)\Theta(n + k)Θ(n+k)\Theta(n + k)Θ(n+k)\Theta(n + k)yesnono
Radix sort (LSD)Θ(d(n+k))\Theta(d(n + k))Θ(d(n+k))\Theta(d(n + k))Θ(d(n+k))\Theta(d(n + k))Θ(n+k)\Theta(n + k)yesnono
Bucket sortΘ(n)\Theta(n)Θ(n)\Theta(n) expected (uniform keys)Θ(n2)\Theta(n^2)Θ(n)\Theta(n)yesnono

Number of exchanges: selection sort makes at most n−1n - 1; bubble sort makes exactly II; insertion sort makes II shifts; heapsort makes Θ(nlg⁡n)\Theta(n \lg n) in general.

Choosing a sort

SituationGood choiceReason
Small nn, or nearly sorted inputinsertion sortΘ(n+I)\Theta(n + I), tiny overhead
Guaranteed O(nlg⁡n)O(n \lg n) with O(1)O(1) extra spaceheapsortin place with that worst case among the standard implementations in this table
Stability needed with O(nlg⁡n)O(n \lg n) worst casemerge sortstable and optimal
Common efficient in-memory choice for arraysquicksort (randomized or median-of-three)small constants, in place
Linked listmerge sortno random access needed
Writes are expensiveselection sortat most n−1n - 1 exchanges
Integer keys in a small rangecounting sortΘ(n+k)\Theta(n + k)
Fixed-length integer or string keysradix sortΘ(d(n+k))\Theta(d(n + k))
Data larger than memoryexternal merge sortsequential passes

Important properties and observations

  • Stable sorts in the table. bubble, insertion, merge, counting, radix, bucket. Unstable: selection (array form), quicksort, heapsort. Any sort can be made stable by sorting pairs (key,original index)(\text{key}, \text{original index}), at the cost of extra space.
  • In place. bubble, selection, insertion, heapsort, and quicksort (stack excepted). Merge sort on arrays and the three linear-time sorts are not.
  • Already sorted input. insertion sort and flagged bubble sort take Θ(n)\Theta(n); quicksort with a first or last pivot takes Θ(n2)\Theta(n^2); merge sort stays Θ(nlg⁡n)\Theta(n \lg n); heapsort does too for distinct keys, but duplicate-heavy sorted inputs can be faster; selection sort stays Θ(n2)\Theta(n^2).
  • All keys equal. insertion and bubble Θ(n)\Theta(n); heapsort Θ(n)\Theta(n); Lomuto quicksort Θ(n2)\Theta(n^2); three-way quicksort Θ(n)\Theta(n).
  • Lower bound statements. "every comparison sort takes Ω(nlg⁡n)\Omega(n \lg n) time on some input" is true; "every comparison sort takes Ω(nlg⁡n)\Omega(n \lg n) time on every input" is false (insertion sort on sorted input takes Θ(n)\Theta(n)).

GATE examination perspective

  • "Which sort" questions. match the stated constraint (stability, space, worst case, nearly sorted input) with the table above.
  • Counting questions. minimum comparisons for max, min-and-max, second largest, merging, or sorting a few keys; use the exact formulas and check the parity of nn.
  • Lower-bound reasoning. decision tree height ≥⌈lg⁡(n!)⌉\ge \lceil \lg(n!) \rceil; every leaf depth ≥n−1\ge n - 1 (best case of any comparison sort); Ω(nlg⁡k)\Omega(n \lg k) for inputs whose keys are within kk of their place; for partial problems, count the outcomes the algorithm must distinguish (for example, (2nn)\binom{2n}{n} possible interleavings when merging, giving at least lg⁡(2nn)\lg \binom{2n}{n} comparisons).
  • Traps. heapsort's best case on distinct keys is still Θ(nlg⁡n)\Theta(n \lg n); quicksort is in place but not stable; merge sort is stable but not in place; the Ω(nlg⁡n)\Omega(n \lg n) bound is a worst-case and average-case bound, not a best-case one.

Summary

Sources

  1. T. H. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein, Introduction to Algorithms, 3rd ed., MIT Press, 2009: Section 8.1 (lower bounds for sorting, decision trees, Theorem 8.1), Section 9.1 (minimum and maximum) and Exercise 9.1-1 (the second smallest element in n + ⌈ lg n ⌉ - 2 comparisons).

Next steps