基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。
将所有待比较数值统一为同样的位数长度,位数较短的前面补零,然后从最低位开始,依次进行一次排序,这样从最低为排序,一直到最高位排序完成之后,数列就变成了一个有序序列
//基数排序
public static int[] radixSort(int[] arr){
//设置一个二维数组充当桶,行表示第几个桶(共10个桶 0~9),列表示桶的容量
int[][] bucket=new int[10][arr.length];
//定义一个一维数组记录每个桶的存放数据
int[] nums=new int[10];
int searchMax=seachMax(arr);//寻找出数组中最大元素的位数
int p=0;
while(p<=searchMax){
for(int i=0;i<arr.length;i++){
int num=(int)(arr[i]/(Math.pow(10,p))%10);
bucket[num][nums[num]]=arr[i];
nums[num]++;
}
p++;
int index=0;
for(int i=0;i< 10;i++){
if(nums[i]!=0){
for(int j=0;j<nums[i];j++){
arr[index++]=bucket[i][j];
}
}
nums[i]=0;//统计完个位数并排序后将此数组的值清零,为其统计十位数做准备
}
}
return arr;
}
//查找数组中最大元素的位数
private static int seachMax(int[] arr){
int max=arr[0];
for(int num:arr){
if(max<num){
max=num;
}
}
return max+"".length();//让max+""后转化为字符串型,再求出其长度,则为整型数的长度
}
//存在负数的解决方法,找出最小值,若最小值为负数,则让数组中所有的数加上最小的负数,之后再减去此数
稳定性:若数组中出现重复元素,若排序后重复元素还按照源数组中的先后顺序排列,则称之为稳定,否则为不稳定
in-place:不占用额外内存
out-place:占用额外内存
n:数据规模
d 为位数,r 为基数,n 为原数组个数
排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
---|---|---|---|---|---|---|
基数排序 | O(d*(n+r)) | O(d*(n+r)) | O(d*(n+r)) | O(n+r) | out-place | 稳定 |
原文:https://www.cnblogs.com/ekig/p/14723384.html