概念
基数排序属于“分配式排序”,又称“桶子法”,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O(nsqrt(n))(x为最高位数),空间复杂度为(10n)而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法
————————来自《百度百科》。
用人话说就是加强变异拓展版的桶排,可分为LSD和MSD两种。
手动举例
排序542,642,7168,32,49,73,645,62,4123,4356,921,349。
记每位上的数为关健值
第一步:根据个位数将其分配
1:921
2:542,642,32,62
3:73,4123
5:645,
6:4356,
8:7168
9:349,49
第二步:将其整理为一个序列921,542,642,32,62,73,4123,645,4356,7168,349,49,再根据十位数将其分配
2:921,4123
3:32
4:542,642,645,349,49
5:4356,
6:62,7168
7:73
第三步:将其整理为一个序列921,4123,32,542,642,645,349,49,4356,62,7168,73,接着按百位排序
0:32,49,62,73
1:4123,7168
3:349,4356
5:542
6:642,645,
9:921,
同理,将其整理成一个序列,按千位排序
0:32,49,62,73,349,542,642,645,921
4:4123,4356
7:7168
于是排序好了:32,49,62,73,349,542,642,645,921,4123,4356,7168。
这是LSD做法,即从最小位开始排序,一直排到最高位;如果位数多的话,使用MSD的效率会比较好。MSD的方式与LSD相反,是由高位数为基底开始进行排序,不同的是MSD再排完第一遍后,在其内部再进行MSD。
实现方法
LSD:先从第k个关健值开始排序,再对第k-1个关健值进行排序,依次重复,直到对第1个关健值排序后便得到一个有序序列。
MSD:先按第1个关健值排序分组,同一组中记录,第1个关健值相等,再对各组按第2个关健值排序分成子组,之后,对后面的关键码继续这样的排序分组,直到第k个关健值对各子组排序后。再将各组连接起来,便得到一个有序序列。
上排序代码
#include<bits/stdc++.h>
using namespace std;
int cl(int a,int b){
a/=pow(10,b-1);
return a%10;
}
int al[20][1000002],x[1000002],n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&x[i]);
for(int i=1;i<=9;i++){
memset(al,0,sizeof(al));
for(int j=1;j<=n;j++){
int xt=cl(x[j],i);
al[xt][++al[xt][0]]=x[j];
}
int t=0;
for(int j=0;j<=9;j++) for(int k=1;k<=al[j][0];k++) x[++t]=al[j][k];
}
for(int i=1;i<=n;i++) printf("%d ",x[i]);
return 0;
}