3.6.7 · D5Sorting & Searching

Question bank — Radix sort — LSD, MSD; O(d(n+k))

1,575 words7 min readBack to topic

Before we start, one shared vocabulary reminder so no symbol is unearned:


True or false — justify

Radix sort escapes the comparison lower bound
True — it never asks "is ?" between whole keys, so the Comparison Sort Lower Bound (which only binds comparison sorts) simply does not apply.
LSD radix sort with an unstable per-digit sort still ends up correct
False — stability is the load-bearing assumption of the induction; without it, ties on the current digit can scramble the order earlier passes built, and correctness collapses.
Radix sort is always
False — hides a logarithm; if keys grow like then and the cost returns to .
Making the radix larger always makes radix sort faster
False — bigger cuts the pass count but inflates the count array; past the term dominates and you lose, so there is a sweet spot near .
MSD radix sort must examine every digit of every key, just like LSD
False — MSD can stop a bucket as soon as it holds element, so a distinguishing prefix (e.g. the first letter of "apple" vs "zebra") is enough; LSD alone reads all digits.
Counting sort inside each pass could be replaced by quicksort without changing correctness
False for LSD — quicksort is not stable, and LSD requires stability; you would also reintroduce comparisons, defeating the purpose (see Counting Sort).
The space cost of radix sort is
True — one output array of size plus one count array of size ; nothing else scales, so the total auxiliary space is .
Radix sort works on negative integers with no modification
False — digit extraction assumes non-negative keys; negatives need an offset (add a bias) or a signed-aware final pass, or they sort into wrong positions.
Both LSD and MSD can be made stable
True — LSD is stable by construction; MSD is stable too if each bucket preserves input order and buckets are concatenated in radix order (see Stability in Sorting).
Radix sort and Bucket Sort are the same algorithm
False — bucket sort distributes by value range then sorts each bucket; radix sort distributes by one digit repeatedly using a stable count. They share the "scatter into buckets" idea but differ in the key they bucket on.

Spot the error

"I ran LSD placement left-to-right instead of right-to-left; order is fine."
Wrong — walking the input left-to-right while decrementing the prefix-count reverses ties, breaking stability; you must iterate the input in reverse for the pass to stay stable.
"My prefix-sum loop is for i in range(k): count[i] += count[i]."
Wrong — it must add the previous bucket: count[i] += count[i-1]; adding count[i] to itself just doubles a value and produces garbage offsets.
" is the number of elements, so more data means more passes."
Wrong — is the number of digit positions of the largest key , not ; adding more elements of the same width does not add passes.
"Radix sort compares digits, so it's still a comparison sort."
Wrong — it never compares two digits to decide order; it indexes by digit value into a count array, which is why the comparison lower bound does not apply.
"I chose (binary) to make the count array tiny and it's the fastest choice."
Wrong — maximizes , so you do the most passes possible; tiny trades a small count array for a huge pass count and is usually slowest.
"MSD gives me sorted order after processing just the first digit."
Wrong — only the top-level order is fixed after digit 0; within each bucket the elements are still unsorted until the recursion descends further.
"I wrote (x / exp) % k with a single slash to grab a digit."
Wrong — single / is real (float) division, so you get a fraction and the modulo misbehaves; you need integer division // (i.e. floor division) to isolate a clean digit.

Why questions

Why must LSD start from the least significant digit, not the most?
Because the most significant digit dominates value: sorting it last (with stability preserving all lower-digit work) lets the final pass impose the correct top-level order while ties fall back to already-sorted lower digits.
Why does stability alone guarantee correctness in the LSD induction?
Because keys equal on the current (higher) digit keep their prior relative order, and that prior order was already correct on all lower digits — so no already-done work is ever undone.
Why is one counting-sort pass and not ?
The tally and placement loops are , but zeroing and prefix-summing the count array touches all buckets, adding a term that matters when is large relative to .
Why does MSD suit variable-length strings better than LSD?
MSD reads keys front-to-back and can stop once a prefix distinguishes them, so short-but-different strings need little work; LSD must align on a fixed width and read every character (see Tries for the same prefix idea).
Why doesn't radix sort violate the comparison lower bound theorem?
The theorem only lower-bounds comparison-based sorts; radix sort extracts information from key structure via indexing, a channel the theorem never accounts for (see Big-O Notation and Comparison Sort Lower Bound).
Why pick for 32-bit integers?
One byte per pass gives passes and a 256-entry count array that is negligible beside large — a balance between few passes and a small count array.

Edge cases

What does radix sort do with an empty array?
Returns it unchanged — the loop bound maxv // exp > 0 is never entered (there is no max ), so zero passes run, which is correct.
What happens when all keys are identical?
Every pass drops them all into a single bucket and stability keeps their input order; the result equals the input, which is trivially sorted — no wasted correctness, just full passes of work.
How many passes for a single-element array or all single-digit keys?
Exactly pass, since gives so only the units position exists; the loop runs once and stops.
What if some keys have fewer digits than the max (e.g. 2 among 802)?
Missing high-order digits are treated as by , so shorter keys land in bucket on those passes and correctly sort as smaller — no padding needed.
What is when is exactly a power of , say ?
because has four digits (the leading 1 plus three zeros); using 3 would drop that top digit and misplace . Note is the wrong formula here — always use .

Active Recall

Recall One-line answers to the four core traps

Stable? :: So ties on the current digit keep the order earlier passes already sorted. ? :: , the digit-count of the biggest key . MSD wins? :: On variable-length keys where a short prefix separates most elements. Always ? :: No — if keys are as large as , .