When elements have small integer keys, you can sort them in time without comparisons. These linear sorts beat the comparison-sort lower bound by exploiting key structure.
Counting sort
Given integers in range :
1. Allocate a count array of length . 2. Make one pass over the input, incrementing counts. 3. Compute prefix sums of the count array (turning counts into starting positions). 4. Make a second pass over the input, placing each element at its position and advancing.
Time: . Space: for the output and count arrays. Stable.
When counting sort wins
is small relative to . Sorting RGB byte values (). Sorting ages (). Sorting exam scores in a class (). Linear time, no comparisons, very cache-friendly.
When it loses
is large. Sorting 32-bit integers () directly with counting sort allocates 16 GB. Sorting floats — counting sort doesn't apply.
Radix sort
Sort by one digit at a time, using a stable inner sort (usually counting sort). For 32-bit integers, do 4 passes of 1 byte each. Total time: where is the number of digits/bytes and is the base.
For random 32-bit integers, that's about work plus count-array overhead. Radix sort beats quicksort on uniform integer data by a real margin.
Bucket sort
Partition the value range into buckets; insert each value into its bucket; sort each bucket and concatenate. expected when values are uniformly distributed. Used in floating-point sorting and in massively-parallel sorting systems.