Skip to content

Least Significant Byte Sort

LSD radix sort variant that processes keys byte by byte from least significant to most significant.

Least Significant Byte sort is the byte oriented version of LSD radix sort. It processes fixed width keys one byte at a time, starting from the least significant byte and moving toward the most significant byte.

It relies on a stable inner sorting step, usually counting sort with 256 buckets.

Problem

Given an array AA of fixed width integer keys, sort the array in increasing order.

Each key can be written as:

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

where each did_i is a byte:

0di<256 0 \le d_i < 256

Idea

Sort the array by byte positions in increasing order of significance:

d0,d1,,dm1 d_0, d_1, \ldots, d_{m-1}

After each pass, the array is sorted by the processed suffix of bytes.

Algorithm

lsb_sort(A, bytes):
    for p from 0 to bytes - 1:
        stable_counting_sort_by_byte(A, p)

    return A

Byte extraction:

dp=(x>>(8p))&255 d_p = (x >> (8p)) \mathbin{\&} 255

Example

Sort:

A=[513,256,258,1] A = [513, 256, 258, 1]

Byte form:

valuehigh bytelow byte
51321
25610
25812
101

After sorting by low byte:

[256,513,1,258] [256, 513, 1, 258]

After sorting by high byte:

[1,256,258,513] [1, 256, 258, 513]

Correctness

After processing byte pp, the array is sorted by the suffix:

dpdp1d0 d_p d_{p-1}\cdots d_0

The base case holds after sorting by d0d_0. For the inductive step, stable sorting by dpd_p orders elements by the new byte while preserving the ordering of lower bytes.

After all bytes have been processed, the array is sorted by the full key.

Complexity

Let:

  • nn be number of elements
  • mm be number of bytes

Each pass costs:

O(n+256) O(n + 256)

Total time:

O(m(n+256)) O(m(n + 256))

Space:

O(n+256) O(n + 256)

For fixed width integers, mm is constant, so time is linear in nn.

Properties

propertyvalue
stableyes
in placeno
comparison basedno
directionLSD
radix256

When to Use

Use LSB sort when:

  • sorting large arrays of fixed width integers
  • stability is required
  • byte extraction is cheap
  • auxiliary memory is acceptable

Avoid when:

  • memory must be minimal
  • keys are variable length
  • recursive MSD methods perform better on the dataset

Implementation

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

    max_bits = max(a).bit_length()
    bytes_count = (max_bits + 7) // 8

    for p in range(bytes_count):
        count = [0] * 256

        for x in a:
            b = (x >> (8 * p)) & 255
            count[b] += 1

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

        out = [0] * len(a)

        for i in range(len(a) - 1, -1, -1):
            x = a[i]
            b = (x >> (8 * p)) & 255
            count[b] -= 1
            out[count[b]] = x

        a = out

    return a