基数排序是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。
基数排序(只考虑正数)
/**
* 基数排序
* 只考虑正数
*/
private void radixSort(int[] nums) {
int max = nums[0];
for (int num : nums) {
if (num > max) {
max = num;
}
}
int maxDigit = String.valueOf(max).length();
//初始化桶
int[][] bucket = new int[10][nums.length];
//桶元素个数计数器
int[] bucketCount = new int[10];
//取位数的因子
int n = 1;
//从各位一直到最高位处理
for (int i = 0; i < maxDigit; i++, n *= 10) {
//遍历所有元素, 获取所在的bucket, 加入bucket中, 计数器加1
for (int j = 0; j < nums.length; j++) {
int index = nums[j] / n % 10;
bucket[index][bucketCount[index]] = nums[j];
bucketCount[index]++;
}
//取出bucket的元素, 重新放回nums中
int index = 0;
for (int j = 0; j < 10; j++) {
if (bucketCount[j] > 0) {
for (int k = 0; k < bucketCount[j]; k++) {
nums[index++] = bucket[j][k];
}
}
//计数器重置为0
bucketCount[j] = 0;
}
}
}
基数排序(考虑正负数)
/**
* 基数排序
* 考虑正负数
* 为避免出现负数, 统一所有值减去最小值
*/
private void radixSort(int[] nums) {
//求最小值和最大值
int max = nums[0];
int min = nums[0];
for (int num : nums) {
max = Math.max(num, max);
min = Math.min(num, min);
}
//求最高位数(统一所有值减去最小值)
int maxDigit = String.valueOf((long)max - min).length();
int[][] bucket = new int[10][nums.length];
int[] bucketCount = new int[10];
int n = 1;
for (int i = 0; i < maxDigit; i++, n *= 10) {
for (int j = 0; j < nums.length; j++) {
//统一所有值减去最小值
int index = (int)(((long)nums[j] - min) / n % 10);
bucket[index][bucketCount[index]] = nums[j];
bucketCount[index]++;
}
int index = 0;
for (int j = 0; j < 10; j++) {
if (bucketCount[j] > 0) {
for (int k = 0; k < bucketCount[j]; k++) {
nums[index++] = bucket[j][k];
}
}
bucketCount[j] = 0;
}
}
}