基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
- 基数排序 vs 计数排序 vs 桶排序
基数排序有两种方法:
这三种排序算法都利用了桶的概念,但对桶的使用方法上有明显差异:
- 基数排序:根据键值的每位数字来分配桶;
- 计数排序:每个桶只存储单一键值;
- 桶排序:每个桶存储一定范围的数值;
import java.util.Arrays;
/**
* @Version :
* @Description : 计数排序
*/
public class RadioSort {
public static void main(String[] args) {
int arr[]={3,2,2,5,4,0,5,4,5,1, 48, 96, -148, -136, -129};
// int arr[]={48, 96, -148, -136, -129};
int[] copy = Arrays.copyOf(arr, arr.length);
int max = getMaxValue(arr);
int maxdigit = getLength(max);
copy = radioSort(copy, maxdigit);
for (int i : copy) {
System.out.print(i + " ");
}
}
// 获取最大值
public static int getMaxValue(int[] arr) {
int max = arr[0];
for (int value : arr) {
if (value > max) {
max = value;
}
}
return max;
}
// 获取最大值长度
public static int getLength(int value) {
if (value == 0 ){
return 1;
}
int count = 0;
while (value != 0) {
count++;
value = value / 10;
}
return count;
}
public static int[] radioSort(int[] arr, int maxdigit) {
int mod = 10; // 取商
int dev = 1; // 取余数
for (int i = 0; i < maxdigit; i++, mod *= 10, dev *= 10) {
// 20个长度[0-9]对应负数,[10-19]对应正数 ,已经够装了,不需要再 int[mod * 2][0]
int[][] buckets = new int[20][0];
for (int j = 0; j < arr.length; j++) {
/**
* 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
* 例如 : 48 96 -148 -136 -129
* _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
* 第一次: -129 -148 -136(-6+10=4) 96 48
* 弹出: -129 -148 -136 96 48
* 第二次: -148(6) -136(7) -129(-129%100=-29/10 =-2+10=8) 48 96
* 弹出: -148 -136 -129 48 96
*
* -129 96(0+10)
* -136 48
* 第三次: -148(-1+10=9)
*/
int index = (arr[j] % mod) / dev + 10;
// System.out.println("index:" + index + " mod: " + mod + " dev " + dev);
buckets[index] = appendA(buckets[index], arr[j]);
}
// 重新入桶
int sortedIndex = 0;
for (int[] bucket : buckets) {
for (int value : bucket) {
arr[sortedIndex++] = value;
}
}
}
return arr;
}
public static int[] appendA(int[] arr, int value) {
// 复制数组可以增加数组的长度
arr = Arrays.copyOf(arr, arr.length + 1);
arr[arr.length - 1] = value;
return arr;
}
}