import java.util.Arrays;
/**
* 桶排序 基数排序
*/
public class BucketSort {
public static void main(String[] args) {
int[] arr = {1092, 98, 24, 222, 1, 8, 77};
radixSort(arr);
System.out.println(Arrays.toString(arr));
}
//桶排序
public static void radixSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
radixSort(arr, maxbits(arr));
}
public static void radixSort(int[] arr, int maxbits) {
//10进制
final int radix = 10;
//i = 1代表进行以个位为基准arr数组的调整,i = 2代表进行以十位为基准对arr调整
for (int i = 1; i <= maxbits; i++) {
/*
count[]下标既代表索引亦代表数字某一位的值.假定在调整数字的个位时,
个位等于索引值,那么该索引的数据 +1,就可统计出词频.
如: [0, 1, 2, 0, 1, 0, 0, 1, 2, 0]
*/
int[] count = new int[radix];
//count[]统计个十百千 ... 上对应数的词频
for (int j = 0; j < arr.length; j ++) {
int idx = getBit(arr[j], i, radix);
count[idx] = count[idx] + 1;
}
/*
由上述生成的count[]改造成count'[]
如:
[0, 1, 2, 0, 1, 0, 0, 1, 2, 0]
变成:
[0, 1, 3, 3, 4, 4, 4, 5, 7, 7]
解释: 前缀和
*/
for (int j = 1; j < count.length; j ++) {
count[j] = count[j - 1] + count[j];
}
//倒序遍历arr数组放入help[]
int[] help = new int[arr.length];
for (int j = arr.length - 1; j >= 0; j --) {
int idx = getBit(arr[j], i, radix);
int hidx = count[idx];
help[hidx - 1] = arr[j];
count[idx] = count[idx] - 1;
}
for (int j = 0; j < arr.length; j++) {
arr[j] = help[j];
}
}
}
//指定位上的数,int bit,bit = 1时取数字个位的值,bit = 2取十位的值
public static int getBit(int num, int bit, int radix) {
return bit == 1 ? num % 10 : (num % (int) (Math.pow(radix, bit))) / (int) (Math.pow(radix, bit - 1));
}
//获取数组中最大数的位数
private static int maxbits(int[] arr) {
int min = Integer.MIN_VALUE;
for (int value : arr) {
if (value > min) {
min = value;
}
}
int bits = 0;
while (min > 0) {
min /= 10;
bits++;
}
return bits;
}
}
左神算法学习