Visualizer CodeViz · Algorithms, visualized

Part II · Radix sorts · week 5

LSD radix sort

Sort by the last character, then the one before it, and so on. Each pass only works because the previous passes' order survives — stability doing real work.

Run the animation, step by step → generated live from any input you type — nothing is pre-recorded

Cost and properties

timeO(w · n) — w = key length
compareszero
needsfixed-length keys
classic usepunched-card sorters

Reference: Sedgewick & Wayne, §5.1; Hollerith 1887.

LSD radix sort in Python

Runnable as-is, and written for reading. Watch the highlighted line move through it in the animation, or send it straight to the visualizer — it arrives with a test case ready to run, yours to edit.

Open in Visualizer

def lsd_sort(a, w):
    # a is a list of w-character strings. Key-indexed counting on
    # character d, for d = w-1 down to 0. It works ONLY because each pass
    # is stable: earlier passes' order survives inside equal characters.
    # R is the RADIX -- the alphabet size. 26 here because the keys are
    # lowercase words, so a letter's digit is ord(c) - ord('a'). Use 256
    # and ord(c) for arbitrary bytes; nothing else about the code changes.
    R, n, A = 26, len(a), ord('a')
    aux = [None] * n
    for d in range(w - 1, -1, -1):        # RIGHT to LEFT
        count = [0] * (R + 1)
        for i in range(n):
            count[ord(a[i][d]) - A + 1] += 1
        for r in range(R):
            count[r + 1] += count[r]
        for i in range(n):
            aux[count[ord(a[i][d]) - A]] = a[i]
            count[ord(a[i][d]) - A] += 1
        for i in range(n):
            a[i] = aux[i]
    return a

Why it works

Why right to left

The last pass sorts on the most significant character, so it decides the overall order. Within a group of keys that agree on that character, the order left behind by the previous pass survives — because each pass is stable — and that order was correct for the remaining characters. Induct backwards and the whole thing is sorted after w passes.

Do it left to right with the same code and it is simply wrong: the later passes destroy the earlier work. Left-to-right requires recursion into groups, which is MSD.

The cost

w passes over n keys: O(w·n) — linear in the total input size, and independent of how the keys are arranged. For 7-character licence plates that is 7 passes no matter how many million plates you have, beating n log n comfortably. Note it examines every character of every key, even when the first one already decides the answer.

Punched cards

This algorithm predates computers. Hollerith's card sorters (1887 census) worked exactly this way: a mechanical sorter distributed cards into bins by one column, the operator stacked the bins in order, and repeated for the next column to the left. “Stacking the bins in order” is stability, implemented in cardboard.

Limitations

Keys must be the same length — real implementations pad, or switch to MSD for variable-length strings. And R counters are allocated per pass, so for a large alphabet with few keys the R term dominates. It is also not in place: aux is the same size as the input.

What to try in the animation

All keys must have the same length. The default is the course's 3-character example; the licence-plate preset is the historical use case.

The animation is generated from the input box, in your browser — press Animate after editing it. To execute the Python itself, use Open in Visualizer above.

Open LSD radix sort in the player →

The rest of Radix sorts