基数排序

1.大体思路
基数排序是一种整数排序算法,先写出提取整数每一位数字的子函数,然后从最低位开始(必须是从最低位开始),依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。

2.代码

#include <iostream>
#include <algorithm>
#include <ctime>
using namespace std;

//const int N = 5;

void InitArr(int *nArr, int nLen) {     //初始化数组
    srand(time(NULL));
    for(int i = 0; i < nLen; ++i) {
        nArr[i] = rand() % 500;
        //nArr[i] = i;
    }
}

void PrintArr(int *nArr, int nLen) {
    for(int i = 0; i < nLen; ++i) {
        cout << nArr[i] << " ";
    }
    cout << endl;
}

void Swape(int *p1, int *p2) {
    int nTmp = *p1;
    *p1 = *p2;
    *p2 = nTmp;
}

void RandomSort(int *nArr, int nLen) {
    srand(time(NULL));
    for(int i = 0; i < nLen; ++i) {
        int nIndex = rand() % nLen;
        Swape(&nArr[i], &nArr[nIndex]);
        //Sleep(2000);                       //等待2s,更新随机种子
    }
}

//获取每一位上的数字
int Digit(int nNum, int w) {
    int nTmp = 1;
    for(int i = 0; i < w - 1; ++i) {
        nTmp *= 10;
    }
    return (nNum / nTmp) % 10;
}

void RadixSort(int *nArr, int nLen, int w) {
    int i;
    int radixArrays[10][nLen + 1];
    for(i = 0; i < 10; ++i) {
        radixArrays[i][0] = 0;  //此处记录这组数据的个数
    }

    for(int pos = 1; pos <= w; ++pos) {  //从个位开始,且只能从个位开始
        for(i = 0; i < nLen; ++i) { //分配过程
            int num = Digit(nArr[i], pos);
            int index = ++radixArrays[num][0];
            radixArrays[num][index] = nArr[i];
        }

        int j = 0;
        for(i = 0; i < 10; ++i) {  //收集
            for(int k = 1; k <= radixArrays[i][0]; ++k) {
                nArr[j++] = radixArrays[i][k];
            }
            radixArrays[i][0] = 0;  //复位
        }
        PrintArr(nArr, nLen);
    }
}


int main() {
    int Len = 20;
    int Arr[Len];
    InitArr(Arr, Len);
    PrintArr(Arr, Len);
    RandomSort(Arr, Len);
    PrintArr(Arr, Len);
    cout << endl;
    RadixSort(Arr, Len, 3);
//    PrintArr(Arr, Len);

    return 0;
}

3.运行结果
这里写图片描述

4.总结
基数排序的时间复杂度是 O(k*n) ,其中 n 是排序元素个数,k 是数字位数,注意这不是说这个时间复杂度一定优于 O(nlogn),k的大小取决于数字位的选择(比如比特位数),和待排序数据所属数据类型的全集的大小;k决定了进行多少轮处理,而 n 是每轮处理的操作数目,k≈logB(N), B表示每一位存在不同数的个数,N是待排序数据集全集的势(可以理解为最大值),关键码的取值范围为radix,一趟分配时间复杂度为O(n),一趟收集时间复杂度为O(radix),共进行k趟分配和收集。
如果考虑和比较排序进行对照,基数排序的形式复杂度虽然不一定更小,但由于不进行比较,因此其基本操作的代价较小,而且在适当选择的 B 之下,k一般不大于 log n,所以基数排序一般要快过基于比较的排序,比如快速排序。
基数排序属于非比较排序
基数排序的效率和初始序列是否有序没有关联。
基数排序属于稳定排序。
裸的基数排序只针对非负整数进行排序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值