计数排序是一个非基于比较的排序算法。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比较排序算法。当然这是一种牺牲空间换取时间的算法。
基本思想
计数排序的基本思想是:对每一个输入元素 x,确定小于 x 的元素个数。例如,如果有7个元素小于 x,则 x 就应该在第8个输出位置上。
运行过程
- 准备:
输入数组:array
[1…n]。
输出数组:result
[1…n]。
临时储存数组:countArray
[0…k]。 - 计算
array
中每个元素的个数,存放到countArray
数组:将array
数组中的元素值作为countArray
数组的下标,array
中元素每重复出现一次countArray
数组对应元素+1。 - 计算小于
array
数组中小于当前元素的个数=countArray
数组当前元素中与前一个元素的加和。并将数据更新到countArray
数组中 - 根据
countArray
数组中小于当前元素的个数来确定array
数组中元素在result
数组中的存放位置。
代码实现
/**
* 计数排序
* @param array 待排序数组
* @param k 临时数组长度,取值为排序数组的最大值+1
* (此处是因为 array 中的元素被作为数组下标,所以数组长度为最大值+1)
*/
private static void countSort(int[] array, int k) {
//创建计数统计数组
int[] countArray = new int[k];
//计算 array 中每个元素的重复个数
for (int i = 0; i < array.length; i++) {
countArray[array[i]] += 1;
}
//计算数组中小于当前元素的元素个数
for (int i = 0; i < k; i++) {
if (i > 0) {
countArray[i] = countArray[i] + countArray[i - 1];
}
}
//结果输出数组
int[] result = new int[array.length];
//将 array 中的元素存放到 result 指定位置
for (int i = array.length - 1; i >= 0; i--) {
System.out.println("array:" + array[i] + " | countArray:" + countArray[array[i]]);
//计算存放位置(小于当前元素的数量值-1即为数组下标)
int pos = countArray[array[i]] -1;
//根据计数统计数组将数组array中的元素存放到result数组中
result[pos] = array[i];
//小于当前元素的数量值-1
countArray[array[i]] = pos;
}
System.out.println(Arrays.toString(result));
}
迟到的更新,哈哈。计数排序感觉是一个并不常用到的算法,不过思路相对其他比较排序是比较清奇,值得了解学习。