算法简介
计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
算法描述
- 找出待排序的数组中最大和最小的元素;
- 统计数组中每个值为 i 的元素出现的次数,存入数组 C 的第 i 项;
- 对所有的计数累加(从 C 中的第一个元素开始,每一项和前一项相加);
- 反向填充目标数组:将每个元素 i 放在新数组的第 项,每放一个元素就将 减去 1。
动图演示
代码实现
public class Counting {
public static int[] countSort(int[] arr) {
if(arr == null || arr.length < 2) return arr;
int n = arr.length;
int max = arr[0];
// 寻找数组的最大值
for (int i = 1; i < n; i++) {
if(max < arr[i])
max = arr[i];
}
//创建大小为max的临时数组
int[] temp = new int[max + 1];
//统计元素i出现的次数
for (int i = 0; i < n; i++) {
temp[arr[i]]++;
}
int k = 0;
//把临时数组统计好的数据汇总到原数组
for (int i = 0; i <= max; i++) {
for (int j = temp[i]; j > 0; j--) {
arr[k++] = i;
}
}
return arr;
}
}
复杂度分析
计数排序是一个稳定的排序算法。当输入的元素是 个 0 到 之间的整数时,时间复杂度是 ,空间复杂度也是 ,其排序速度快于任何比较排序算法。当 不是很大并且序列比较集中时,计数排序是一个很有效的排序算法。但这是一种牺牲空间换取时间的算法,而且当 的时候其效率反而不如基于比较的排序。