基数排序
来源:互联网 发布:时时彩搭建源码 编辑:程序博客网 时间:2024/06/05 16:21
基本思想
将待排数据中的每组关键字依次进行桶分配。
实质是一种考虑多关键字的排序算法。
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):(根据最低位)
输出为:
930、063、083、184、505、278、008、109、589、269
再对上面的序列接着进行针对k2的桶分配:
输出序列为:
505、008、109、930、063、269、278、083、184、589
最后针对k3的桶分配,(最高位)
输出序列为:
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为桶的数量。
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- 基数排序
- JS 中元素的各种位置尺寸宽高
- Ajax-note
- 1020. 月饼
- PAT甲级1055. The World's Richest (25)
- DPDK中文-DPDK工具
- 基数排序
- 深入理解Java虚拟机JVM高级特性与最佳实践阅读总结——第二章 Java内存区域与内存溢出异常
- vue.js中使用set方法
- angular 在controller中共享数据的几种方式
- c语言 2D-FFT(fft2)及IFFT
- eclipse通过maven-archetype-plugin插件创建项目原型
- spring学习(一)
- git常用操作
- AlloyTouch之select选择插件