基数排序

基数排序

一、算法描述

以整形为例,将整形10进制按每位拆分,然后从低位到高位依次比较各个位。主要分为两个过程:
(1)分配,先从个位开始,根据位值(0-9)分别放到0~9号桶中(比如53,个位为3,则放入3号桶中)
(2)收集,再将放置在0~9号桶中的数据按顺序放到数组中
重复(1)(2)过程,从个位到最高位(比如32位无符号整形最大数4294967296,最高位10位)
以[2, 13, 35, 99, 5, 10, 64, 28, 17, 6]为例,具体过程如下:
由于该数组中最大值只有2位,因此只需要进行两次分配与收集过程。
(1)个位的分配与收集
分配:
0: 10
1:
2: 2
3: 13
4: 64
5: 35,5
6: 6
7: 17
8: 28
9: 99
收集:
10 2 13 64 35 5 6 17 28 99
(2)百位的分配与收集
分配:
0: 2,5,6
1: 10,13,17
2: 28
3: 35
4:
5:
6: 64
7:
8:
9: 99
收集:
2 5 6 10 13 17 28 35 64 99
在数据中最高位为2,进行了两次分配、收集过程后,变成有序数组。

二、算法分析

/*
    找到num的从低到高的第pos位的数据
    num: 一个整型数据
    pos: 表示要获得的整型的第pos位数据
*/
int getNumInPos(int num, int pos)
{
    int temp = 1;
    for(int i = 0; i < pos - 1; i++)
        temp *= 10;

    return (num/temp)%10;
}

/*
    找到数组中最大元素的位数
    a[]: 输入数组
    n: 数组元素个数
    返回最大元素的位数
*/
int findMaxDigit(int a[], int n)
{
    // 查找最大元素
    int max_num = a[0];
    for(int i = 1; i < n; i++)
    {
        if(max_num < a[i])
            max_num = a[i];
    }

    // 判断最大元素的位数
    int digit = 0;
    while(max_num != 0)
    {
        max_num = max_num/10;
        digit++;
    }

    return digit;
}

/*
    基数排序
    a[]: 输入数组
    n: 数组元素个数
*/
// 整型排序
#define RADIX_INT 10
void radixSort(int a[], int n)
{
    // 分别为0-9的序列空间
    int *radixArrays[RADIX_INT];
    for(int i = 0; i < RADIX_INT; i++)
    {
        radixArrays[i] = (int *)malloc(sizeof(int)*(n + 1));
        // index为0处记录这组数据的个数
        radixArrays[i][0] = 0;
    }

    // 求出数组中最大元素的位数
    int digit = findMaxDigit(a, n);
    // 从最低位到最高位
    for(int pos = 1; pos <= digit; pos++)
    {
        // 分配过程
        for(int i = 0; i < n; i++)
        {
            int num = getNumInPos(a[i], pos);
            int index = ++radixArrays[num][0];
            radixArrays[num][index] = a[i];
        }
        // 收集过程
        for(int i = 0, j = 0; i < RADIX_INT; i++)
        {
            for(int k = 1; k <= radixArrays[i][0]; k++)
            {
                a[j++] = radixArrays[i][k];
            }
            // 复位
            radixArrays[i][0] = 0;
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值