Intuition The ONE core idea
A number like 802 is not a single thing — it is a sequence of digits 8 , 0 , 2 in a fixed base. If we can sort a pile of numbers by looking at just one digit column at a time (and never comparing two whole numbers), we can sort faster than the "compare two things" limit. This page builds — from nothing — every symbol you need to see why that trick even makes sense.
Before you can trust the radix-sort machine in the parent note , you must own every piece of notation it fires at you. We build them in order, each one on top of the last. Nothing is used before it is drawn.
Definition Digit and place value
A digit is one symbol from a fixed alphabet of size k (for decimal, the ten symbols 0 , 1 , … , 9 ). A whole number is a row of digits , where each column carries a weight : the rightmost column counts ones, the next counts k s, the next counts k 2 s, and so on.
Look at the figure below. The number 802 is drawn as three stacked columns. The picture is the whole point: a number is not atomic — it is addressable by position .
The value is rebuilt from its columns like this:
802 = col 2 8 × 1 0 2 + col 1 0 × 1 0 1 + col 0 2 × 1 0 0
Intuition Why the topic needs this
Radix sort's entire strategy is "sort by column 0, then column 1, ...". If a number were an indivisible blob you could only compare two blobs. Because it is a sequence of columns , we can process one column across all numbers at once. Every symbol below exists to name a piece of this picture.
k = radix
k is the number of distinct symbols a single digit can be. In the picture above, each column can only show one of 0..9 , so k = 10 . If we chose to read numbers in bytes, one "digit" would be one byte and k = 256 .
The picture below shows the tray rack for k = 10 : ten labelled bins, digit 0 on the left to digit 9 on the right. Remember this rack — it is literally the count array in the parent's code.
Intuition Why the topic needs
k
The topic exploits structure : keys are sequences over an alphabet of size k . Choosing k is a design knob — bigger k means each digit carries more information (fewer columns) but more trays. This is the tension the parent's "choosing the radix" example resolves. It connects directly to Counting Sort , which needs exactly k counters.
n = number of elements
n counts the items in the array — the pile of cards, not their digits. In the parent's list [ 170 , 45 , 75 , 90 , 802 , 24 , 2 , 66 ] , we have n = 8 .
Common mistake The two easiest symbols to swap
Why it's tempting: n and k both count "how many". Why it's wrong: n = how many numbers in the pile; k = how many symbols a single digit can be. In [ 170 , 45 , … ] decimal, n = 8 but k = 10 regardless of pile size.
n vs k ::: n counts items in the array; k counts possible digit values (trays).
d = number of digit positions
d is how many columns the widest key needs. In our example the biggest key is 802 , which has 3 columns, so d = 3 . Every LSD pass handles one column, so d is the number of passes.
How do we compute d without drawing columns? We ask: how many times must I multiply k by itself before I pass the biggest key? That question is answered by a logarithm.
Definition Logarithm base
k , written log k
log k ( m ) asks: "To what power must I raise k to reach m ?" It undoes raising k to a power. Example: log 10 ( 1000 ) = 3 , because 1 0 3 = 1000 .
The figure shows the staircase of powers of 10 and where 802 lands.
Intuition Why the topic needs
d
d is the only factor multiplying the per-pass cost. Whether radix sort beats O ( n log n ) hinges entirely on whether d stays small. So d is not decoration — it is the headline of the running-time formula.
The parent code plucks column i out of a number with (x // exp) % k. Three symbols hide here; we build each.
exp = the place weight (k i )
exp is 1 , k , k 2 , … — it selects which column you are reading . To read column i you first shift it down to the ones place with // exp, then chop off everything above it with % k.
Worked digit extraction on 802 (base 10 ):
column 0 : ( 802 // 1 ) % 10 = 2 column 1 : ( 802 // 10 ) % 10 = 0 column 2 : ( 802 // 100 ) % 10 = 8
// exp then % k, in that order
// exp slides the column you want into the ones position (division shifts right). % k then keeps only that one column and discards the higher ones (modulo chops the top off). Reverse the order and you would strip digits before aligning them — you'd read the wrong column.
Extract column i ::: ( x // k i ) % k
O ( f ( n )) is a promise about growth shape , not exact counts. Saying one counting-sort pass is O ( n + k ) means: as the input grows, the work grows at most like n + k (up to a constant multiplier). Constants and slower-growing terms are dropped.
We build this properly in Big-O Notation . Here you only need the reading: O ( d ( n + k )) means "do d passes, each costing about n + k work". The picture below contrasts n log n (comparison sorts) against a flat n line (radix when d is a small constant).
Intuition Why the topic needs Big-O
The whole selling point is "escape Ω ( n log n ) ". Ω is Big-O's mirror — a lower bound, "grows no slower than". Comparison sorts are stuck at Ω ( n log n ) (see Comparison Sort Lower Bound ); radix dodges it because it never compares whole keys. Without Big-O you cannot even state that claim.
A sort is stable if items that tie on the sort key come out in the same relative order they went in. If Alice's 45 was before Bob's 45 before sorting, it stays before after.
Intuition Why stability is load-bearing
Radix sorts column by column. When two numbers tie on the current column, their correct order was already decided by the earlier (lower) columns. Stability is the promise that the current pass won't scramble that earlier work. Break stability and the parent's induction proof collapses. This is the entire subject of Stability in Sorting , and it is why the per-digit engine is Counting Sort (naturally stable) and not, say, an in-place quicksort.
Stable means ::: ties keep their original relative order
LSD = L east S ignificant D igit first: start at column 0 (rightmost), march left. Flat loop of d passes.
MSD = M ost S ignificant D igit first: start at the leftmost column, split into k buckets, then recurse inside each bucket.
MSD's recursion-into-buckets is exactly the shape of a trie and cousins the divide-of-Bucket Sort ; LSD is the flat, always-d -passes workhorse. The parent note compares them in full — here you only need the two names and that they differ in direction and structure .
Place value: a number is columns of digits
Radix k: k symbols, k trays
Extract digit: floor div and modulo
Counting Sort: one stable pass
Stability: ties keep order
Test yourself — say the answer aloud, then reveal.
What does the radix k count The number of distinct symbols one digit can be, i.e. the number of trays/buckets.
What does n count, versus k n = items in the array; k = possible digit values. They are unrelated.
Give the formula for d d = ⌈ log k ( max key + 1 )⌉ — the column count of the widest key.
What does log k ( m ) ask "To what power must I raise k to reach m ?" — it undoes exponentiation.
How do you extract column i of key x ( x // k i ) % k — shift down by k i , then keep the ones column mod k .
Why // exp before % k Division aligns the wanted column into the ones place; modulo then keeps only that column.
What does O ( d ( n + k )) read as in words Do d passes, each costing about n + k work.
What does "stable" guarantee Items tying on the current key keep their original relative order.
Why does radix sort need stability So a later column's pass does not scramble the ordering earlier columns already fixed.
LSD vs MSD in one word each LSD = rightmost-first flat loop; MSD = leftmost-first recurse-into-buckets.