基数排序算法 (Radix Sort)

按数位(个、十、百)三轮递增 FIFO 队列分配与顺序收集,O(N) 线性分配非比较典范

📖 算法原理:按位稳定排序与 FIFO 收集

基数排序(Radix Sort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。它通过多轮基数分配,实现全局排序。

📐 LSD 低位优先基数排序流程

对于含有三位数大数值的序列,我们从最低有效位(个位)开始进行稳定排序:

  1. 个位分发与收集(Units Digit):
    • 扫描所有数字,提取个位数字(例如 124 % 10 = 4)。
    • 将元素推进到对应的基数槽队列中(共有 0 到 9 共 10 个 FIFO 队列箱)。
    • 按先进先出(FIFO)顺序依次出队收集。此时,数组以个位为基准有序。
  2. 十位分发与收集(Tens Digit):
    • 高亮十位数字(例如 (124 / 10) % 10 = 2)。
    • 再次分配并顺序 FIFO 收集。此时,数组以低二位为基准有序。
  3. 百位分发与收集(Hundreds Digit):
    • 高亮百位数字并分发收集。此时,数组全局完全有序!

🚀 复杂度断言: 若最大数有 $D$ 位,数值基数为 $R$(十进制 $R=10$),则每轮稳定分配的时间复杂度为 $O(N + R)$,共进行 $D$ 轮。总时间复杂度为 $O(D \cdot (N + R))$,当 $D$ 为常数时,这是极速的线性时间复杂度!

输入 8 个 0-999 之间的整数(逗号隔开),点击“开始基数排序”观摹三轮分配收集。
🗂️ 个/十/百位 FIFO 队列分配收集仪 (FIFO Radix Bins Playground)
0
1
2
3
4
5
6
7
8
9
收集区准备中
void radixSort(int arr[], int n) {
    // 找出最大数以确定最高位数轮次
    int mx = getMax(arr, n);
    
    // 按位计数排序:exp = 1(个位), 10(十位), 100(百位)...
    for (int exp = 1; mx / exp > 0; exp *= 10) {
        countSort(arr, n, exp); 
    }
}

void countSort(int arr[], int n, int exp) {
    int output[n];
    int count[10] = {0};
    
    // 统计各数字出现频次并计算前缀和
    for (int i = 0; i < n; i++) count[(arr[i]/exp)%10]++;
    for (int i = 1; i < 10; i++) count[i] += count[i-1];
    
    // 反向扫描保证稳定排序, 填入 output
    for (int i = n - 1; i >= 0; i--) {
        int d = (arr[i] / exp) % 10;
        output[count[d] - 1] = arr[i];
        count[d]--;
    }
}
📋 基数分配收集历史