基数排序

基数排序思想逻辑

基数排序思想比较简单,例如有这么一个数组A[14,59,62,88,16]。
第一次,比较个位数,得到数组A1[62,14,16,88,59]
第二次,比较十位数,得到数组A2[14,16,59,62,88]。

具体是怎么实现的呢?
分配10个桶,桶编号为0-9,以个位数数字为桶编号依次入桶,变成下边这样

| 0 | 0 | 62 | 0 | 14 | 0 | 16 | 0 | 88 | 59 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |桶编号

将桶里的数字顺序取出来, 输出结果:[62,14,16,88,59]
再次入桶,不过这次以十位数的数字为准,进入相应的桶,变成下边这样:
由于前边做了个位数的排序,所以当十位数相等时,个位数字是由小到大的顺序入桶的,就是说,入完桶还是有序

| 0 | 14,16 | 0 | 0 | 0 | 59 | 62 | 0 | 88 | 0 |
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |桶编号

基数排序时间效率分析

时间效率:设待排序列为n个记录,d个关键码,关键码的取值范围为radix,则进行链式基数排序的时间复杂度为O(d(n+radix)),其中,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行d趟分配和收集。 空间效率:需要2*radix个指向队列的辅助空间,以及用于静态链表的n个指针。

基数排序代码

#include <iostream>
using namespace std;

int32_t GetMaxBit(int32_t numList[], int32_t len) {
    auto digit = 1;
    for (auto i = 0; i < len; i++) {
        auto tmp = 10;
        while (numList[i] > tmp) {
            digit += 1;
            tmp *= 10;
        }
    }

    return digit;
}

void RadixSort(int32_t numList[], int32_t len) {
    auto digit = GetMaxBit(numList, len);
    vector<int32_t> tmpList(len);
    vector<int32_t> count(10);
    auto radix = 1;

    for (auto i = 0; i < digit; i++) {
        for (auto j = 0; j < len; j++) {
            //统计每个桶中将要放的总数
            auto bit = (numList[j] / radix) % 10;
            count[bit]++;
        }

        for (auto j = 1; j < 10; j++) {
            //对每个桶中的每个数值重新定位:
            //比如第一个桶有2个数字,第二个桶有1个数字,那么第二个桶中的这个数字的排序应该是在第一个桶的2个数字后面
            count[j] += count[j - 1];
        }

        for (auto j = len - 1; j >= 0; j--) {
            //把每个桶中的数字按顺序存起来
            auto bit = (numList[j] / radix) % 10;
            tmpList[count[bit] - 1] = numList[j];
            count[bit]--;
        }

        for (auto j = 0; j < len; j++) {
            numList[j] = tmpList[j];
        }

        radix *= 10;
    }
}

void main() {
    int32_t numList[] = { 31, 41, 59, 26, 48, 58, 12, 5, 90, 10, 9, 6, 45};
    int32_t len = sizeof(numList) / sizeof(numList[0]);
    RadixSort(numList, len);


    for (auto num : numList) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}

返回排序算法分析总结

点赞