基数排序
package aStudy.day6;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
/**
* @author haoqi
* @Date 2020/10/4 - 10:16
* 基数排序
* 桶排序的优化,利用空间换时间
*
*/
public class data07 {
public static void main(String[] args) {
// int arr[] = { 53, 3, 542, 748, 14, 214}; //最高百分位,只进行 个 十 百 三轮排序
int[] arr = new int[80000]; //数据过大会撑爆内存 注意!!! //Java heap space
for (int i = 0; i < 80000; i++) {
arr[i] = (int) (Math.random()*80000); // [0,80000);
}
System.out.println("第0轮,对个位的排序处理 arr =" + Arrays.toString(arr)); //[53, 3, 542, 748, 14, 214]
// radisSort01(arr);
//测试效率
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//1
Date data1 = new Date();
String date1Str = simpleDateFormat.format(data1);
System.out.println("排序前的时间是=" + date1Str);
radisSort01(arr);
//0
Date data2 = new Date();
String date2Str = simpleDateFormat.format(data2);
System.out.println("排序前的时间是=" + date2Str);
// System.out.println("基数排序后 " + Arrays.toString(arr));
// 排序前的时间是=2020-10-04 11:03:05
// 排序前的时间是=2020-10-04 11:03:05
}
public static void radisSort(int[] arr){
//定义二维数组,表示10个桶,每个桶表示一维数组,存放对应位的值
//1. 二维数组包含10个一维数组
//2. 为了防止在放入数的时候,数据溢出,则每个一维数组(桶),大小定为arr.length
//3. 名明确,基数排序是使用空间换时间的经典算法
int[][] bucket = new int[10][arr.length]; //arr.length 防止栈溢出
//为了记录每个桶中,实际存放了多少个数据,我们定义一个一维数组来记录各个桶的每次放入的数据个数
//可以这里理解
//比如:bucketElementCounts[0] , 记录的就是 bucket[0] 桶的放入数据个数
int[] bucketNum = new int[10];
//第1轮,对于每个元素的个位,进行排序处理放相应入桶中
for (int j = 0; j < arr.length; j++) {
//取出每个元素个位值
int digitVal = arr[j]/1%10;
//放入对应的桶中
bucket[digitVal][bucketNum[digitVal]] = arr[j];
bucketNum[digitVal]++;//==
}
//桶的顺序(然后一维数组下标依次弹出数据,放入原来的数组)
int index = 0;
//遍历每个桶,有数据才放人原来的数组
for (int k = 0; k < bucketNum.length; k++) {
if (bucketNum[k] != 0){
//循环k桶(第k个一维数组)放入
for (int l = 0; l < bucketNum[k]; l++) {
//取出元素,放到arr中
arr[index++] = bucket[k][l];
}
}
//处理完数据后,要将每个 bucketNum[k] = 10 !!! 进行归位
bucketNum[k] = 0;
}
System.out.println("第1轮,对个位的排序处理 arr =" + Arrays.toString(arr)); //[542, 53, 3, 14, 214, 748]
//同理,以后每轮只需要取出相应轮的 分位值 即可
//第2轮,对于每个元素的个位,进行排序处理放相应入桶中
for (int j = 0; j < arr.length; j++) {
//取出每个元素个位值
int digitVal = arr[j]/10%10; //取出相应轮的 分位值 即可
//放入对应的桶中
bucket[digitVal][bucketNum[digitVal]] = arr[j];
bucketNum[digitVal]++;//==
}
//桶的顺序(然后一维数组下标依次弹出数据,放入原来的数组)
index = 0;
//遍历每个桶,有数据才放人原来的数组
for (int k = 0; k < bucketNum.length; k++) {
if (bucketNum[k] != 0){
//循环k桶(第k个一维数组)放入
for (int l = 0; l < bucketNum[k]; l++) {
//取出元素,放到arr中
arr[index++] = bucket[k][l];
}
}
//处理完数据后,要将每个 bucketNum[k] = 10 !!! 进行归位
bucketNum[k] = 0;
}
System.out.println("第2轮,对个位的排序处理 arr =" + Arrays.toString(arr)); //[3, 14, 214, 542, 748, 53]
//第2轮,对于每个元素的个位,进行排序处理放相应入桶中
for (int j = 0; j < arr.length; j++) {
//取出每个元素个位值
int digitVal = arr[j]/100%10; //取出相应轮的 分位值 即可
//放入对应的桶中
bucket[digitVal][bucketNum[digitVal]] = arr[j];
bucketNum[digitVal]++;//==
}
//桶的顺序(然后一维数组下标依次弹出数据,放入原来的数组)
index = 0;
//遍历每个桶,有数据才放人原来的数组
for (int k = 0; k < bucketNum.length; k++) {
if (bucketNum[k] != 0){
//循环k桶(第k个一维数组)放入
for (int l = 0; l < bucketNum[k]; l++) {
//取出元素,放到arr中
arr[index++] = bucket[k][l];
}
}
//处理完数据后,要将每个 bucketNum[k] = 10 !!! 进行归位
bucketNum[k] = 0;
}
System.out.println("第2轮,对个位的排序处理 arr =" + Arrays.toString(arr)); //[3, 14, 53, 214, 542, 748]
}
//======================================
//封装
public static void radisSort01(int[] arr){
//找到数组中最大数
int max = arr[0]; //假设第一数就是最大数
for (int i = 0; i < arr.length; i++) {
if (arr[i] > max)
max = arr[i];
}
//得到最大数是几位数
int maxLength = (max + "").length();
int[][] bucket = new int[10][arr.length]; //arr.length 防止栈溢出
int[] bucketNum = new int[10]; //记录桶里面的元素
//每轮排序操作改为循环
for (int i=0,n=1 ; i < maxLength; i++,n*=10) {
//第i轮,对于每个元素的个位,进行排序处理放相应入桶中
for (int j = 0; j < arr.length; j++) {
//取出每个元素个位值
int digitVal = arr[j]/n%10;
//放入对应的桶中
bucket[digitVal][bucketNum[digitVal]] = arr[j];
bucketNum[digitVal]++;//==
}
//桶的顺序(然后一维数组下标依次弹出数据,放入原来的数组)
int index = 0;
//遍历每个桶,有数据才放人原来的数组
for (int k = 0; k < bucketNum.length; k++) {
if (bucketNum[k] != 0){
//循环k桶(第k个一维数组)放入
for (int l = 0; l < bucketNum[k]; l++) {
//取出元素,放到arr中
arr[index++] = bucket[k][l];
}
}
//处理完数据后,要将每个 bucketNum[k] = 10 !!! 进行归位
bucketNum[k] = 0;
}
// System.out.println("第i轮,对个位的排序处理 arr =" + Arrays.toString(arr)); //[542, 53, 3, 14, 214, 748]
}
}
}