public class RadixSort {
public static void main(String[] args) {
// int[] arr = {542,53,3,14,214,748};
// 时间复杂度 O(n+k) 稳定性好的 一种排序算法
int [] arr = new int[80000];
int[] temp = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
// 生成 [0,8000000)的随机数
arr[i] = (int) (Math.random()*8000000);
}
long start_Time = System.currentTimeMillis();
radixSort(arr);
long stop_Time = System.currentTimeMillis();
System.out.printf("耗费 %d ms",stop_Time - start_Time);
}
// 基数排序推导过程版
public static void radix(int[] arr){
//排序几轮是根据数组中的最大值的位数来决定的 例如 最大值是三位数的排序只用排三轮就能排序完成
// 第一轮(针对每个元素的个位进行排序处理)
/**
* 定义一个二维数组,表示10个桶,每一个桶就是一个一维数组
* 二维数组包含10个一维数组
* 为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr.length
* 基数排序使用空间换时间的算法
*/
int[][] bucket = new int[10][arr.length];
/**
* 创建一个一维数组 记录每个桶中实际存放了多少个数据,
* bucketElementCounts [0] 记录的就是bucket[0]桶中的放入数据的个数
*/
int[] bucketElementCounts = new int[10];
for (int i = 0; i <arr.length ; i++) {
// 取出每个元素的个位数来决定存放到那个桶中
int num =arr[i] % 10 ;
//bucketElementCounts[num]++ 第num 桶中有了多少个数据
bucket[num][bucketElementCounts[num]++] = arr[i] ;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int intdex = 0;
//遍历每一个桶。并将桶中有数据的值,放入到原数组中
for (int i = 0; i < bucketElementCounts.length; i++) {
// 判断是否有是数据的桶才进入取出数据 减少循环次数
if(bucketElementCounts[i] !=0){
for (int j = 0; j < bucketElementCounts[i]; j++) {
arr [intdex++] = bucket[i][j];
}
}
}
intdex =0;
System.out.println("========第一轮=========");
System.out.println(Arrays.toString(arr));
System.out.println("========第二轮=========");
bucketElementCounts = new int[10];
for (int i = 0; i <arr.length ; i++) {
// 取出每个元素的十位数来决定存放到那个桶中
int num =arr[i] /10% 10 ;
//bucketElementCounts[num]++ 第num 桶中有了多少个数据
bucket[num][bucketElementCounts[num]++] = arr[i] ;
}
//遍历每一个桶。并将桶中有数据的值,放入到原数组中
for (int i = 0; i < bucketElementCounts.length; i++) {
// 判断是否有是数据的桶才进入取出数据 减少循环次数
if(bucketElementCounts[i] !=0){
for (int j = 0; j < bucketElementCounts[i]; j++) {
arr [intdex++] = bucket[i][j];
}
}
}
intdex =0;
System.out.println(Arrays.toString(arr));
System.out.println("========第三轮=========");
bucketElementCounts = new int[10];
for (int i = 0; i <arr.length ; i++) {
// 取出每个元素的百位数来决定存放到那个桶中
int num =arr[i] /100 ;
//bucketElementCounts[num]++ 第num 桶中有了多少个数据
bucket[num][bucketElementCounts[num]++] = arr[i] ;
}
//遍历每一个桶。并将桶中有数据的值,放入到原数组中
for (int i = 0; i < bucketElementCounts.length; i++) {
// 判断是否有是数据的桶才进入取出数据 减少循环次数
if(bucketElementCounts[i] !=0){
for (int j = 0; j < bucketElementCounts[i]; j++) {
arr [intdex++] = bucket[i][j];
}
}
}
System.out.println(Arrays.toString(arr));
}
// 最终版
public static void radixSort(int[] arr){
int[][] bucket = new int[10][arr.length];
int[] bucketElementCounts = new int[10];
int intdex = 0;
// 找出最大值 决定了排序的轮数
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(max < arr[i]){
max = arr[i];
}
}
// 获取排序的轮数
int maxLength = (max +"").length();
for (int j = 0, n =1 ; j <maxLength ; j++ , n *= 10) {
for (int i = 0; i <arr.length ; i++) {
// 取出每个元素的位数来决定存放到那个桶中
int num =arr[i] /n % 10 ;
//bucketElementCounts[num]++ 第num 桶中有了多少个数据
bucket[num][bucketElementCounts[num]++] = arr[i] ;
}
intdex =0;
//遍历每一个桶。并将桶中有数据的值,放入到原数组中
for (int i = 0; i < bucketElementCounts.length; i++) {
// 判断是否有是数据的桶才进入取出数据 减少循环次数
if(bucketElementCounts[i] !=0){
for (int k = 0; k < bucketElementCounts[i]; k++) {
arr [intdex++] = bucket[i][k];
}
}
// 获取了数据之后重新把每一个元素置为零
bucketElementCounts[i] =0;
}
// System.out.printf("第%d轮排序:%s\n",j+1,Arrays.toString(arr));
}
}
}
八大排序之桶排序
最新推荐文章于 2024-06-28 15:08:54 发布