Radix Sort
Sort by one digit at a time, from least significant to most significant. Each digit sort uses counting sort (which is stable, preserving previous digit order). O(d·(n+k)) where d = number of digits.
Fixed-width keys, so I sort digit by digit with a stable pass each time. Least significant first, and the stability is what preserves earlier work.
How It Works
Radix sort orders integers by processing one digit position at a time, least significant first, using a stable sort (almost always counting sort) for each pass. Stability is the linchpin: when the pass for digit d finishes, ties on digit d retain the order established by all lower digits, so after the final, most significant pass the array is fully sorted.
With d digit positions and base k, the cost is O(d * (n + k)); choosing base 256 makes d small (four passes for 32-bit values) while keeping the per-pass count array tiny. For bounded-size integers d is a constant, so radix sort is effectively linear (beating comparison sorts asymptotically) at the price of O(n + k) auxiliary space and integer-like keys only. The MSD variant recurses from the most significant digit instead and suits variable-length strings.
Step-by-Step Visualization
Code
Tips & Gotchas
Practice Problems
- 1Maximum Gap
- 2Sort an Array
- 3Query Kth Smallest Trimmed Number
About the Linear-Time Sorts Pattern
These bypass the O(n log n) barrier by NOT comparing elements. Instead, they use the values directly. The catch: they only work when values fall within a known, bounded range.
Sorting enables binary search, two-pointer, and greedy. Always ask: can I sort first? Custom comparators solve tricky ordering problems. Know QuickSelect for O(n) expected Kth element.
Common Sorting Interview Problems
- Sort Colors
- Kth Largest Element
- Merge Intervals
- Largest Number
- Sort List
- Meeting Rooms
Frequently Asked Questions
Why must radix sort go least-significant-digit first with a stable inner sort?
Each pass sorts on one digit while stability preserves the ordering created by all previous, lower-significance passes. By induction, after sorting on digit d the array is correctly ordered on the number formed by digits 0..d; an unstable inner sort would scramble those earlier results and break the invariant.
If radix sort is linear, why isn't it the default everywhere?
Its O(d*(n+k)) advantage only materializes when keys are fixed-width integers or strings and d stays small; it needs O(n+k) working memory, has weaker cache behavior across multiple full passes, and cannot handle arbitrary comparator-defined orderings. General-purpose libraries need comparator support, so they ship comparison sorts.
How do I radix sort negative numbers?
The digit passes treat bit patterns as unsigned, which would order negatives after positives. Either offset all values into a non-negative range first, or flip the sign bit before sorting and flip it back afterwards; for floats, a similar monotonic bit transformation exists.