【Algorithm】基数排序

一. 算法描述

  基数排序(以整形为例),将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为三个过程:
  1. 分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
  2. 收集,再将放置在0~9号桶中的数据按顺序放到数组中
  3. 重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)
  下面以【521 310 72 373 15 546 385 856 187 147】序列为例,具体细节如下图所示:

二. 算法实现

#include<stdio.h>
#define MAX 20
#define SHOWPASS
#define BASE 10

// 打印数组
void print(int *a, int n) {
    int i;
    for (i = 0; i < n; i++) {
        printf("%d	", a[i]);
    }
}

// 基数排序
void radixsort(int *a, int n) {
    int i, b[MAX], m = a[0], exp = 1;
    
    // 得到数组的最大值
    for (i = 1; i < n; i++) {
        if (a[i] > m) {
            m = a[i];
        }
    }
 
    while (m / exp > 0) {
        int bucket[BASE] = { 0 };
    
        for (i = 0; i < n; i++) {
            bucket[(a[i] / exp) % BASE]++;
        }
 
        for (i = 1; i < BASE; i++) {
            bucket[i] += bucket[i - 1];
        }

        for (i = n - 1; i >= 0; i--) {
            b[--bucket[(a[i] / exp) % BASE]] = a[i];
        }
 
        for (i = 0; i < n; i++) {
            a[i] = b[i];
        }
 
        exp *= BASE;
 
        #ifdef SHOWPASS
            printf("
PASS   : ");
            print(a, n);
        #endif
        }
    }
 
int main() {
    int arr[MAX];
    int i, n;
    printf("请输入总元素数目 (n <= %d) : ", MAX);
    scanf("%d", &n);
    n = n < MAX ? n : MAX;
 
    printf("请输入 %d 个元素 : 
", n);
    for (i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
 
    printf("
排序前  : ");
    print(&arr[0], n);
 
    radixsort(&arr[0], n);
 
    printf("
排序之后 : ");
    print(&arr[0], n);
    printf("
");
 
    return 0;
}

三. 算法分析

  • 平均时间复杂度:O(dn)(d即表示整形的最高位数)
  • 空间复杂度:O(rn) (r表示0~9,用于存储临时的序列) 
  • 稳定性:稳定

参考资料

  [1] http://blog.csdn.net/cjf_iceking/article/details/7943609

  [2] http://zh.wikipedia.org/wiki/%E5%9F%BA%E6%95%B0%E6%8E%92%E5%BA%8F

  [3] http://baike.baidu.com/view/1617233.htm?fr=aladdin

原文地址:https://www.cnblogs.com/ningvsban/p/3800744.html