基数排序

百度百科上写的代码像是一坨翔。

1.

基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用。

2.基数排序的实现方法分为两种:

最高位优先(Most Significant Digit first)法,简称MSD法:先按k1排序分组,同一组中记录,关键码k1相等,再对各组按k2排序分成子组,之后,对后面的关键码继续这样的排序分组,直到按最次位关键码kd对各子组排序后。再将各组连接起来,便得到一个有序序列。
最低位优先(Least Significant Digit first)法,简称LSD法:先从kd开始排序,再对kd-1进行排序,依次重复,直到对k1排序后便得到一个有序序列。

3.LSD基数排序的原理及代码实现如下:

第一步

假设原来有一串数值如下所示:

73, 22, 93, 43, 55, 14, 28, 65, 39, 81

首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:

0

1 81

2 22

3 73 93 43

4 14

5 55 65

6

7

8 28

9 39

第二步

接下来将这些桶子中的数值重新串接起来,成为以下的数列:

81, 22, 73, 93, 43, 14, 55, 65, 28, 39

接着再进行一次分配,这次是根据十位数来分配:

0

1 14

2 22 28

3 39

4 43

5 55

6 65

7 73

8 81

9 93

第三步

接下来将这些桶子中的数值重新串接起来,成为以下的数列:

14, 22, 28, 39, 43, 55, 65, 73, 81, 93

这时候整个数列已经排序完毕;如果排序的对象有三位数以上,则持续进行以上的动作直至最高位数为止。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int getDigitNum(int x){
    if(x == 0) return 1;
    int res = 0;
    while(x){
        res ++;
        x /= 10;
    }
    return res;
}
void RadixSort(int data[], int n){
    //find the Maximum and its digit number
    int Max = data[0];
    for(int i = 1; i < n; i++){
        if(Max < data[i]) Max = data[i];
    }
    int maxNum = getDigitNum(Max);
    //maxNum times radix sort
    int divisor = 1;
    for(int k = 0; k < maxNum; k++){
        vector<int> g[10];//g[i]中包含了"末位"数字是i的data[]数组中的元素
        for(int i = 0; i < 10; i++) g[i].clear();
        for(int i = 0; i < n; i++){
            int tmp = data[i] / divisor % 10;
            g[tmp].push_back(data[i]);
        }
        int cnt = 0;
        for(int i = 0; i < 10; i++){
            for(int j = 0; j < g[i].size(); j++){
                data[cnt++] = g[i][j];
            }
        }
        divisor *= 10;
    }
}
int main(){
    int Array[10] = {73,22,93,43,55,14,28,65,39,81};
    RadixSort(Array, 10);
    for(int i = 0; i < 10; i++){
        printf("%d ", Array[i]);
    }
    printf("\n");
    return 0;
}


 


 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值