package com.company.排序;
import java.util.Arrays;
public class 基数排序 {
public static void main(String[] args) {
int a[]=new int[]{1,3,6,9,14,0,89,4,5};
radixSort(a);
System.out.println(Arrays.toString(a));
}
public static void radixSort(int[] arr) {
int max=arr[0];//假设第一个数就是最大数
for(int i=1;i<arr.length;i++) {
if(arr[i]>max) {
max=arr[i];
}
}
int maxLength=(max+" ").length();
//第一轮(针对每个元素的个位进行排序处理)
//定义一个二维数组,表示10个桶,每个桶就是一维数组
//说明:
//1.二维数组包含10个一维数组
//2.为了防止在放入数的时候,数据溢出,则每个一个数组(桶),大小定为arr.length
//3明显,基数排序是使用空间换时间
int[][] bucket=new int[10][arr.length];
// 为了记录每个桶中,实际存放了多少个数据,我们定义了一个一维数组来记录各个桶中的个数
int[] bucketElementCounts=new int[10];
for(int i=0,n=1;i<maxLength;i++,n*=10) {
for(int j=0;j<arr.length;j++) {
//取出每个元素的对应位的值进行排序处理,第一次是个位,第二次是十位。。。
int digitOfElement=arr[j]/n%10;
//放入到对应的桶中
bucket[digitOfElement][bucketElementCounts[digitOfElement]]=arr[j];
bucketElementCounts[digitOfElement]++;
}
//按照这个桶的顺序(一维数组的下标依次取出数据,放入原来数组)
int index=0;
//遍历每一桶,并将桶中的数据,放入到原数组
for(int k=0;k<bucketElementCounts.length;k++) {
//如果桶中,有数据,我们才能放入到原数组
if(bucketElementCounts[k]!=0) {
//循环该桶即第k个桶,(即第k个一维数组),放入
for(int l=0;l<bucketElementCounts[k];l++) {
//取出元素放入arr
arr[index]=bucket[k][l];
index++;
}
}
//第i+1轮处理后,需要将每个bucketElementCounts[k]=0!!!
bucketElementCounts[k]=0;
}
}
}
}
优化版 从二维数组简化到一维数组
public class 基数排序test {
public static void main(String[] args) {
int a[]=new int[]{1,3,6,9,14,0,89,4,5};
radixSort(a);
System.out.println(Arrays.toString(a));
}
public static void radixSort(int[] arr) {
int max = arr[0];//假设第一个数就是最大数
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
int maxLength = (max + " ").length();//获取最大数字的位数
for (int i = 1; i <= maxLength; i++) {
int[] count = new int[10];//定义一个一维数组,表示i位上小于等于下标的数有几个,
int[] bucket = new int[arr.length];//辅助数组 暂存数据
//表示i位上等于下标的数有几个
for (int index = 0; index < arr.length; index++) {
int digit = getDigit(arr[index], i);
count[digit]++;
}
//表示i位上小于等于下标的数有几个,
for(int index=1; index<10; index++){
count[index] += count[index-1];
}
//从后向前遍历 经过此次排序 排第几
for(int index = arr.length-1; index>=0; index--){
int digit = getDigit(arr[index], i);
count[digit]--;
bucket[count[digit]]=arr[index];
}
//重新写回原数组
for(int index = 0; index <arr.length; index++){
arr[index] = bucket[index];
}
}
}
private static int getDigit(int x, int index){//获取第 index 位上的数
for(int i=1; i<index; i++){
x=x/10;
}
return x%10;
}
}