基数排序

本文详细介绍了桶+计数排序算法,首先通过maxBit函数计算输入整数的最大位数,然后进行逐位的桶排序,利用计数记录每个数字出现的频率并重新排列。通过实例演示了如何按个位、十位等进行排序,并展示了整个过程。
摘要由CSDN通过智能技术生成

桶+计数排序

int maxBit(int* a, int len) {//计算最大位数
    int max = a[0],bit=1;
    for (int i = 1; i < len; i++) max = max > a[i] ? max : a[i];
    for (int i = max; i >= 10; i /= 10)bit++;
    return bit;
}
void radixSort(int* a, int len) {
    int bit = maxBit(a, len), k, radix = 1, bucket[10] = { 0 };
    int* temp = new int[len];
    for (int i = 1; i <= bit; i++) {//分别按个位,十位,百位。。进行排序
        for (int j = 0; j < 10; j++)bucket[j] = 0;//先清0
        for (int j = 0; j < len; j++) {
            k = a[j] / radix % 10;//“尾数”
            bucket[k]++;//记录“尾数”0-9出现次数
        }

        for (int j = 1; j < 10; j++)bucket[j] += bucket[j - 1];//计算填入位置//升序
        //for (int j = 8; j >= 0; j--)bucket[j] += bucket[j + 1];//降序

        for (int j = len - 1; j >= 0; j--) {//对于递增序列,越高位记录的数值越大,0到len-1对应尾数0到9,进行十位比较时应该让个位数大的先出去参与比较,FIFO
            k = a[j] / radix % 10;//“尾数”
            temp[bucket[k] - 1] = a[j];//数组下标从0开始,要减1
            bucket[k]--;//下一次要放入前一个位置
        }
        for (int j = 0; j < len; j++)a[j] = temp[j];//排序结果记入a中
        radix *= 10;//按下一个数位排序
    }

    delete[] temp;
}

void test02() {
    //sizeof(a) / sizeof(*a)
    int a3[] = { 49,38,65,97,76,13,27,49 };
    int a5[] = { 15,1,2,3,5,8,4,9,6,7 };
    int a2[] = { 1,2,3,4,5,7,8,9,10,6 };
    int a4[] = { 1,2,3,4,5,7,8,9,10,6 };
    int a6[] = { 8,3,6,4,2,1,5,7,9,10,12,11 };
    int a7[] = { 16,9,20,15,3,18,13,2,17,10,5,7,11,12,6,1,19,4,8,14 };
    int a8[] = { 53,17,78,9,45,65,87,32 };
    int a[] = { 53, 3, 542, 748, 14, 214, 154, 63, 616 };
    radixSort(a, sizeof(a) / sizeof(*a));


    for (const int i : a)cout << i << ' '; cout << endl;

}

 结合图来说明。第一轮,按个位排序,a中有个尾数为0的元素,1个尾数为2的元素,3个尾数为3 的元素,则尾数为2的元素放在第1位,尾数为3的元素放在第2,3,4位,这就对应了temp[bucket[k] - 1] = a[j]bucket[k]--的规则。此时“桶”记录的是元素填入的位置。最后一列的tmp就是所有元素按个位排好序的结果,然后更新到原数组a中,再开始下一轮,按十位大小进行排序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值