package com.study.data.structures.sort;
import java.util.Arrays;
/**
* 基数排序
* 所有自然数都是由0到9构成的,所以准备一个二维数组来进行数据的装填
* 定义二维数组,
* int[][] arr = new int[11][arr.length]
* {43, 986, 7, 21, 591, 87}
* <p>
* 第一轮:
* 依次取出待排序元素,并获取该元素的个位数放到其对应的数组中。例如:43%10=3,那么就将43放入到arr[3]
* arr[0]={}
* arr[1]={21,591}
* arr[2]=
* arr[3]={43}
* arr[4]=
* arr[5]=
* arr[6]={986}
* arr[7]={7,87}
* arr[8]=
* arr[9]=
* 结果是:{21,591,43,986,7,87}
* <p>
* <p>
* 第二轮:
* 依次取出待排序元素,并获取该元素的十位数放到其对应的数组中。例如:43/10%10=4,那么就将43放入到arr[4]
* arr[0]={7}
* arr[1]=
* arr[2]={21}
* arr[3]=
* arr[4]={43}
* arr[5]=
* arr[6]=
* arr[7]=
* arr[8]={986,87}
* arr[9]={591}
* 结果是:{7,21,43,986,87,591}
* <p>
* <p>
* 第三轮:
* 依次取出待排序元素,并获取该元素的十位数放到其对应的数组中。例如:43/100%10=0,那么就将43放入到arr[0]
* arr[0]={7,21,43,87}
* arr[1]=
* arr[2]=
* arr[3]=
* arr[4]=
* arr[5]={591}
* arr[6]=
* arr[7]=
* arr[8]=
* arr[9]={986}
* 结果是:{7,21,43,87,591,986}
* <p>
* 一共循环3次,因为数组元素中最大值的位数是3位
*
* 当前基数排序对于负数是存在局限性的:
* 个人认为:
* 如果待排序数组中存在负数的话,可以在第一次基数排序时针对负数做一次收集,然后针对负数进行一次基数排序。
* 最后按照排序规则进行所有数据的合并
*/
public class RadixSort {
public static void main(String[] args) {
int[] arr = {43, 986, 7, 21, 591, 87};
// radixSortDeduction(arr);
int[] arrays = new int[8000000];
for (int i = 0; i < 8000000; i++) {
arrays[i] = (int) (Math.random() * 8000000);
}
long startTime = System.currentTimeMillis();
radixSort(arrays);
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
private static void radixSort(int[] arr) {
//定义一个二维数组,使用arr.length是因为实在无法确定,每个一维数组会装多少元素,所以就去最大值
int[][] radixTemp = new int[10][arr.length];
//用于记录每个一维数组添加数据的个数
int[] radixCount = new int[10];
//先获取待排序数组中的最大数值,用以确定外层循环需要多少次
int max = arr[0];
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, arr[i]);
}
System.out.println(max+"");
int maxLength = (max + "").length();
int index = 0;
for (int i = 0, n = 1; i < maxLength; i++, n *= 10) {
for (int j = 0; j < arr.length; j++) {
int num = arr[j];
int digit = num / n % 10;
//获得下标为digit的数组
int[] currentArr = radixTemp[digit];
//往下标为digit的数组中添加数据
currentArr[radixCount[digit]++] = num;
}
index = 0;
for (int k = 0; k < radixCount.length; k++) {
int count = radixCount[k];
if (count != 0) {
for (int g = 0; g < count; g++) {
arr[index++] = radixTemp[k][g];
}
radixCount[k] = 0;
}
}
// System.out.println("第" + i + "轮::" + Arrays.toString(arr));
}
}
private static void radixSortDeduction(int[] arr) {
//定义一个二维数组,使用arr.length是因为实在无法确定,每个一维数组会装多少元素,所以就去最大值
int[][] radixTemp = new int[10][arr.length];
//用于记录每个一维数组添加数据的个数
int[] radixCount = new int[10];
//第一轮
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
int singleDigit = num % 10;
int[] currentArr = radixTemp[singleDigit];
currentArr[radixCount[singleDigit]++] = num;
}
int index = 0;
for (int i = 0; i < radixCount.length; i++) {
int count = radixCount[i];
if (count != 0) {
for (int j = 0; j < count; j++) {
arr[index++] = radixTemp[i][j];
}
radixCount[i] = 0;
}
}
System.out.println("第一轮::" + Arrays.toString(arr));
//第二轮
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
int singleDigit = num / 10 % 10;
int[] currentArr = radixTemp[singleDigit];
currentArr[radixCount[singleDigit]++] = num;
}
index = 0;
for (int i = 0; i < radixCount.length; i++) {
int count = radixCount[i];
if (count != 0) {
for (int j = 0; j < count; j++) {
arr[index++] = radixTemp[i][j];
}
radixCount[i] = 0;
}
}
System.out.println("第二轮::" + Arrays.toString(arr));
//第三轮
for (int i = 0; i < arr.length; i++) {
int num = arr[i];
int singleDigit = num / 100 % 10;
int[] currentArr = radixTemp[singleDigit];
currentArr[radixCount[singleDigit]++] = num;
}
index = 0;
for (int i = 0; i < radixCount.length; i++) {
int count = radixCount[i];
if (count != 0) {
for (int j = 0; j < count; j++) {
arr[index++] = radixTemp[i][j];
}
radixCount[i] = 0;
}
}
System.out.println("第三轮::" + Arrays.toString(arr));
}
}
算法学习记录010_基数排序
最新推荐文章于 2025-07-28 23:20:14 发布