基数排序

基数排序

基数排序(Radix Sort)是1887年由赫尔曼·何乐礼发明的,基数排序非常适合用于整数排序(尤其是非负整数)。

它的执行流程为:依次对个位数、十位数、百位数、千位数、万位数…,进行排序(从低位到高位)。

个位数、十位数、百位数的取值范围都是固定的0~9,可以使用计数排序对它们进行排序。

思考:如果先对高位排序,再对低位排序,是否可行?不可行。

基数排序图解

基数排序_第1张图片

代码实现

// 找出数组中的最大值
int max = array[0];
for (int i = 1; i < array.length; i++) {
    if (array[i] > max) {
        max = array[i];
    }
}
int[] newArray = new int[array.length]; // 开辟新数组来存放有序的元素
// 每一位的范围是[0,10)
int[] counts = new int[10]; // 存放每个元素出现的次数
// 计算最大值的位数
for (int i = 1; i < max; i *= 10) {
    // 对i位数进行计数排序
    // 统计每一位的次数
    for (int j = 0; j < array.length; j++) {
        counts[array[j] / i % 10]++;
    }
    // 次数累加前面所有的次数
    for (int j = 1; j < counts.length; j++) {
        counts[j] += counts[j - 1];
    }
    // 将旧数组中的值填充到新数组的合适位置
    for (int j = array.length - 1; j >= 0; j--) {
        newArray[--counts[array[j] / i % 10]] = array[j];
    }
    // 将新数组的值复制到旧数组中
    for (int j = 0; j < newArray.length; j++) {
        array[j] = newArray[j];
    }
    // 情况counts,便于下次使用
    for (int j = 0; j < counts.length; j++) {
        counts[j] = 0;
    }
}

上面代码实现的基数排序最好、最坏、平均时间复杂度为O(d∗(n+k)),空间复杂度为O(n+k)(其中d是最大值的位数,k是每一位数的范围),属于稳定排序。

基数排序的另一种实现

基数排序_第2张图片

// 计算出最大值
int max = array[0];
for (int i = 1; i < array.length; i++) {
    if (array[i] > max) {
        max = array[i];
    }
}
// 开辟一个二维数组来存放元素
int[][] arrays = new int[10][array.length];
// 存放二维数组中每个数组放了多少个元素
int[] sizes = new int[10];
// 根据最大值的位数进行排序
for (int i = 1; i <= max; i *= 10) {
    // 计算出每个元素的索引存放在二维数组对应的位置
    for (int j = 0; j < array.length; j++) {
        int index = array[j] / i % 10; // 元素对应的位数是多少,所在的数组就是多少
        arrays[index][sizes[index]++] = array[j];
    }
    // 遍历二维数组中的元素放入原来的数组中
    int t = 0;
    for (int m = 0; m < arrays.length; m++) {
        for (int n = 0; n < sizes[m]; n++) {
            array[t++] = arrays[m][n];
            arrays[m][n] = 0; // 清空二维数组
        }
        sizes[m] = 0; // 清空
    }
}

上面代码实现的基数排序时间复杂度为O(dn),空间复杂度是O(kn+k) (其中d是最大值的位数,k是每一位数的范围)。

更多精彩内容关注本人公众号:架构师升级之路
基数排序_第3张图片

你可能感兴趣的:(数据结构与算法,基数排序)