排序算法(八):基数排序

排序思路:
本文采用LSD(Least significant digital)排序方式,基数取10。

对于给定数组,先按照个位进行排序,再按照十位进行排序,再按照百位进行排序……没有该位的,排序时按0处理。
桶子思想:我们定义“分别选取个位、十位、百位…等进行元素比较”为一轮。每一轮排序过程,我们准备10个清空的桶子,按照0-9的顺序编号,将该位是对应编号的元素,放入对应的“木桶”中(每个桶中正常放入元素即可,不用在乎顺序);归类放置完毕后,从0号桶开始,逐个拿出里面的元素(顺序无所谓),按序(拿出先后)覆盖原给定数组。覆盖完成后,本轮结束。当比较完所有位后,排序结束。
整个过程,桶子会协助排序,这样随着比较位的变化,排序会自然完成。

举例:

{22,35,16,9,5,20} 

1)找出最高比较位
最大值是35,其最高位是十位
2)按照个位进行排序
计算个位:
lsd=2 lsd=5 lsd=6 lsd=9 lsd=5 lsd=0
分别放入桶子:

0:20
1:
2:22
3:
4:
5:35,5
6:16
7:
8:
9:9

然后挨个拿出,覆盖原数组:

{20,22,35,5,16,9} 

3)按照十位进行排序,同理进行“归桶”

0:5,9
1:16
2:20,22
3:25
4:
5:
6:
7:
8:
9:

然后挨个拿出,覆盖原数组:

{5,9,16,20,22,35} 

4)已经排完最高位,排序结束。

c实现:

void radixSort(int array[], int len){

    int tmp[10][len] = {0}; //桶子:储存余数分别为0-9的元素
    int bucket[10] = {0}; //储存余数分别为0-9的元素个数,用于判断该桶子中是否有数。

    int max_val=0;
    int exp=1;
    int exp_max=1;
    int i=0;

    //求可能的最高位(万、千、百)exp_max
    for(i=0; i<len; i++){
        if(array[i]>max_val)
            max_val = array[i];
    }
    while(max_val>=10){
        max_val /= 10;
        exp_max *= 10;
    }

    while(exp<=exp_max) {
        //每次使用桶子前必须要清空
        memset(tmp, 0, sizeof(tmp));
        memset(bucket, 0, sizeof(bucket));

        for (i = 0; i < len; i++) {
            int lsd = (array[i] / exp) % 10; //当前元素求余数
            tmp[lsd][bucket[lsd]++] = array[i]; //当前元素求余数
        }
        int k = 0;
        for (i = 0; i < 10; i++)
            if (bucket[i] > 0) { //若该余数桶中有数
                for (int j = 0; j < bucket[i]; j++) {
                    array[k++] = tmp[i][j]; //按序放入array
                }
            }
        exp *= 10;
    }
}

时间复杂度为:O(Kn),K与最高位有关,n为数组长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值