Skip to content

Radix Sort

Sort integer or string keys by processing one digit, byte, or character position at a time.

Radix sort sorts keys by decomposing them into smaller parts such as digits, bytes, or characters. Instead of comparing whole keys directly, it groups keys by one position at a time.

It is most useful when keys have fixed width or bounded length, such as integers, fixed length strings, byte arrays, or identifiers.

Problem

Given an array AA of nn keys, sort the keys by their full value using their digit representation.

For base bb, each key can be written as:

x=dm1dm2d1d0 x = d_{m-1}d_{m-2}\cdots d_1d_0

where each digit satisfies:

0di<b 0 \le d_i < b

Main Variants

Radix sort has two common directions.

variantdirectiontypical use
LSD radix sortleast significant digit to most significant digitfixed width integers and strings
MSD radix sortmost significant digit to least significant digitstrings, variable length keys, lexicographic sorting

LSD radix sort relies on a stable subroutine, usually stable counting sort. MSD radix sort recursively partitions by leading digits.

LSD Algorithm

radix_sort_lsd(A, digits, base):
    for p from 0 to digits - 1:
        stable_counting_sort_by_digit(A, p, base)

    return A

Here, position 00 means the least significant digit.

Example

Sort:

[329,457,657,839,436,720,355] [329, 457, 657, 839, 436, 720, 355]

Using decimal digits.

After sorting by ones digit:

[720,355,436,457,657,329,839] [720, 355, 436, 457, 657, 329, 839]

After sorting by tens digit:

[720,329,436,839,355,457,657] [720, 329, 436, 839, 355, 457, 657]

After sorting by hundreds digit:

[329,355,436,457,657,720,839] [329, 355, 436, 457, 657, 720, 839]

The final array is sorted.

Correctness

For LSD radix sort, the stable pass on digit pp sorts the array by the lowest p+1p + 1 digits. This holds by induction. The base case follows from sorting by the least significant digit. The induction step works because the stable sort orders by the new digit while preserving the previous order among equal new digits.

After all digit positions have been processed, the array is sorted by every digit, so it is sorted by the full key.

Complexity

Let:

  • nn be the number of keys
  • mm be the number of digit positions
  • bb be the base

Each stable counting pass costs:

O(n+b) O(n + b)

Total time:

O(m(n+b)) O(m(n + b))

Space:

O(n+b) O(n + b)

For fixed width machine integers with constant mm and practical base bb, this is linear in nn.

When to Use

Use radix sort when:

  • keys are integers, bytes, strings, or fixed width records
  • digit extraction is cheap
  • the alphabet or digit range is bounded
  • stable sorting by individual positions is available

Avoid radix sort when keys are large objects with expensive digit extraction, highly variable encodings, or no natural bounded digit representation.

Implementation

def radix_sort(a):
    if not a:
        return a

    max_value = max(a)
    exp = 1
    base = 10

    while max_value // exp > 0:
        a = counting_sort_by_digit(a, exp, base)
        exp *= base

    return a

def counting_sort_by_digit(a, exp, base):
    count = [0] * base

    for x in a:
        digit = (x // exp) % base
        count[digit] += 1

    for i in range(1, base):
        count[i] += count[i - 1]

    out = [0] * len(a)

    for i in range(len(a) - 1, -1, -1):
        x = a[i]
        digit = (x // exp) % base
        count[digit] -= 1
        out[count[digit]] = x

    return out