算法介绍
1)基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是通过键值的各个位的值,将要排序的元素分配至某些“桶”中,达到排序的作用
2)基数排序法是属于稳定性的排序,基数排序法的是效率高的稳定性排序法
3)基数排序(Radix Sort)是桶排序的扩展
4) 基数排序是1887年赫尔曼·何乐礼发明的。它是这样实现的:将整数按位数切割成不同的数字,然后按每个位数分别比较。
5)基数排序是典型的以空间换时间的排序
基本思想
将所有待比较数值统一为同样的数位长度,数位较短的数前面补零。然后,从最低位开始,依次进行一次排序。这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
代码实现
public class BucketSort {
public static void bucketSort(int[] array){
//先确定数组最大数的位数,即确定装桶的次数
int maxValue = array[0];
for (int i = 1; i <array.length ; i++) {
if (maxValue<array[i])
maxValue = array[i];
}
int maxLength = (maxValue+"").length();
//定义一个二维数组,表示10个桶,每个桶就是一个一维数组
// 说明
//1.二维数组包含10个一维数组
// 2.为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr.length
// 3.明确,基数排序是使用空间换时间的经典算法
int[][] bucket = new int[10][array.length];//这是排序过程中需要的内存空间
//为了记录每个桶中实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数
// bucketIndex数组中的每个元素记录的就是每个桶中存入数据的实际数量
int[] bucketIndex = new int[10];
int locationIndex = 0;
///(针对每个元素的对应位进行排序处理),第一次是个位,第二次是十位,第三次是百位..
for (int i = 0,n = 1; i <maxLength ; i++,n*=10) {
for (int j = 0; j < array.length; j++) {
//取出每个元素的对应位的值locationIndex,
// 表示本次基数排序应该放在第几个桶
locationIndex = array[j]/n%10;
//放入对应的桶中locationIndex=3
//表示放入第四个桶的第bucketIndex[locationIndex]位置上
bucket[locationIndex][bucketIndex[locationIndex]] = array[j];
//该桶的存入数据的个数加一
bucketIndex[locationIndex]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int index = 0;
for (int j = 0; j <bucketIndex.length ; j++) {
///如果桶中有数据,我们才放入到原数组
if (bucketIndex[j]!=0){
for (int k = 0; k <bucketIndex[j] ; k++) {//循环该桶即第k个桶(即第k 个一维数组),放入原来的数组中
array[index++] = bucket[j][k];
}
}
//表示将当前这个桶中的数据清零,
//下一轮基数排序又从零开始存储实际是覆盖本轮存取的数据
bucketIndex[j] = 0;
}
}
}
}
测试800万个数据排序耗费时间
int[] array = new int[8000000];
for (int i = 0; i <8000000 ; i++) {//800万个数据进行排序
array[i] = (int)(Math.random()*8000000);
}
long l1 = System.currentTimeMillis();
BucketSort.bucketSort(array);
long l2 = System.currentTimeMillis();
System.out.println("排序花费时间:"+(l2-l1)+"毫秒");