Sorting in linear time
◈ 6 cardsCounting sort Θ(n+k) (stable, reverse pass); radix sort Θ(d(n+k)) (LSD, needs a stable inner sort); bucket sort Θ(n) average — how they dodge the lower bound.
Beating the bound by not comparing
Last lesson: comparison sorts need . The escape is to stop comparing and exploit structure in the keys — then we sort in linear time.
Counting sort —
Assume each key is an integer in . Counting sort uses values as indices, never comparing two keys. Four phases:
- Zero a count array .
- Count: for each , increment — now = number of keys equal to .
- Prefix sums: — now = number of keys , i.e. the position of the last copy of value .
- Place (right to left): for down to , put at and decrement .
Total , which is when . It is stable — equal keys keep their input order — because phase 4 runs right-to-left: the last occurrence of a value lands in the rightmost slot for that value.
Radix sort —
To sort -digit numbers, sort by one digit at a time, least-significant first (LSD), using a stable sort (counting sort) at each pass. Stability is load-bearing: each pass must preserve the order the previous (lower) digits established. By induction, after sorting digit the numbers are correctly ordered on their least-significant digits. With constant and , radix sort is .
Bucket sort — average
Assume keys are i.i.d. uniform on . Scatter into bucket , insertion-sort each bucket, concatenate. Under the uniform assumption each bucket holds elements in expectation, giving average time (worst case if everything clusters into one bucket).
Worked example
Counting sort on with : the counts are , prefix sums make , and the right-to-left placement yields . The runnable exercises do this and a stability demo.