一 计数排序
由于技术排序不是比较排序,所以它的速度比任何比较排序都快,由于要以数组中最大元素作为大小申请数组内存空间,所以对于数据范围大的数组,此方法会很占用内存
代码示例:
/**
* 计数排序
*
* @param arr
*/
public void countSort(int[] arr) {
int maxValue = findTheMax(arr);
int bucketLen = maxValue + 1;
int[] bucket = new int[bucketLen];//新建一个比最大数多一的一个数组(也成为桶)
for (int value : arr) {
bucket[value]++;//将目标数组的值作为计数数组的下标,使此元素加一
}
int sortedIndex = 0;
for (int j = 0; j < bucketLen; j++) {
while (bucket[j] > 0) {
arr[sortedIndex++] = j;
bucket[j]--;
}
}
}
/**
*返回数组最大值
*/
public int findTheMax(int[] arr) {
int maxValue = arr[0];
for (int value : arr) {
if (maxValue < value) {
maxValue = value;
}
}
return maxValue;
}
二 基数排序
/**
* 获取数组中最大元素的位数
*/
public int getMaxDigit(int[] arr) {
//获取最大元素的值
int maxValue = arr[0];
for (int value : arr) {
if (maxValue < value) {
maxValue = value;
}
}
if (maxValue == 0) {
return 1;
}
//判断该元素是几位数
int lenght = 0;
for (long temp = maxValue; temp != 0; temp /= 10) {
lenght++;
}
return lenght;
}
/**
* 重新开辟一个比原数组大一的数组,将值添加到末尾
*
* @param arr
* @param value
*/
public int[] arrayAppend(int[] arr, int value) {
arr = Arrays.copyOf(arr, arr.length + 1);
arr[arr.length - 1] = value;
return arr;
}
/**
* 基数排序
*
* @param arr
* @return
*/
public void radixSort(int[] arr) {
int maxDigit = getMaxDigit(arr);
int mod = 10;
int dev = 1;
//根据最大数的位数进行基数排序
for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
// 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
int[][] counter = new int[mod * 2][0];
for (int j = 0; j < arr.length; j++) {
int bucket = ((arr[j] % mod) / dev) + mod;
counter[bucket] = arrayAppend(counter[bucket], arr[j]);
}
int pos = 0;
for (int[] bucket : counter) {
for (int value : bucket) {
arr[pos++] = value;
}
}
}
}