基数排序

基本思想

将待排数据中的每组关键字依次进行桶分配。
实质是一种考虑多关键字的排序算法。

MSD:

假设我们有一些二元组(a,b),如果我们对a为首要关键字,b为次要关键字进行排序。就称为MSD
我们按照首要关键字排序,把相同的分到一起,这样我们就有了若干个桶,然后再按照次要关键字分别对每一堆进行排序。最后合并,这就是MSD

LSD

从最低有效关键字开始排序。具体看下面:

具体示例:

278、109、063、930、589、184、505、269、008、083

我们将每个数值的个位,十位,百位分成三个关键字: 278 -> k1(个位)=8,k2(十位)=7,k3=(百位)=2。

然后从最低位个位开始(LSD),对所有数据的k1关键字进行桶分配(因为,每个数字都是 0-9的,因此桶大小为10),再依次输出桶中的数据得到下面的序列。

实际我们要先建立桶(LinkedList):(根据最低位)

0123456789
930063184505278109
083008589
269

输出为:

930、063、083、184、505、278、008、109、589、269

再对上面的序列接着进行针对k2的桶分配:

0123456789
505930063278083
008269184
109589

输出序列为:

505、008、109、930、063、269、278、083、184、589

最后针对k3的桶分配,(最高位)

0123456789
008109269505930
063184278589
083

输出序列为:

008、063、083、109、184、269、278、505、589、930

LSD算法实现

    public int getDigit(int x,int d){
        int a[]={1,10,100,1000};
        return (x/a[d])%10;
    }
    //按照数据来定义k进制/每位出现的可能性
    //3位数,还是需要观察,这对输入数据有要求,我要检测这个数据是多少位?
    public void Sort(int[] A){
        int N=A.length, k=10,P=3; //需要观察数据
        int[] tmp=new int[N];
        int[] count=new int[k];//桶 初始化值应该为0
        for(int d=0;d<P;d++){
            //每次循环要对count清空
            for(int j=0;j<N;j++)
                count[j]=0;
            //统计入每个桶的元素个数
            for(int j=0;j<N;j++){
                int i=getDigit(A[j],d);
                count[i]++;
            }
            //算下标, 算出真正对应 A数组的下标
            for(int j=1;j<k;j++){
                count[j]+=count[j-1];
            }
            //数据依次转入桶中
            //必须倒序存进来才对
            for(int j=N-1;j>=0;j--){
                int i=getDigit(A[j],d);
                //index = count[i]-1;
                if(count[i]<1)
                    continue;
                tmp[count[i]-1]=A[j];//放入临时数组
                count[i]--; //对应桶的数据索引减一
            }
            for(int j=0;j<N;j++){
                A[j]=tmp[j];
            }
        }

    }

基数排序还可以用于多关键字排序

例如对扑克牌排序的问题
主位优先排序MSD

思想
我们可以根据花色建立4个桶,然后将52张牌分别放入这4个桶,然后对这4个桶分别排序。 当然我们可能需要调用快排或者其他比较排序算法。
最后把它们合并就可以了。

LSD解决

为次关键字也就是面值建立13个桶,结果因为扑克牌就只有13种值,故其实我们分配到13个桶之后就已经排好序了。

实质来说,当主位的基数个数大于次位的时候,主位优先更快。

效率分析

设元素个数为N,整数进制为B,LSD的趟数为P(也就是我们的位数),则最坏的时间复杂度是:
O(P(N+B))
因为每一趟我们要收集分配这些数到我们的桶中,其实对于每一趟来说,我们做的事情和桶排序是一样的。(因为我们不需要对桶里面的内容进行排序,而仅仅是分配)
基数排序的空间复杂度是
O(M+N) M为桶的数量。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值