计数排序(CountingSort)
1.1概述
计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。计数排序(Counting sort)是一种稳定的排序算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序。
1.2描述
- 找出待排序的数组中最大和最小的元素;
- 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
- 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
- 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
1.3代码
package countingsort;
import java.util.Arrays;
/**
* @author xgj
*/
public class CountingSort {
public static void main(String[] args) {
int[] res = new int[]{1,6,5,4,6,2,7,9};
int[] ints = CountingSort.countingSort(res);
System.out.println(Arrays.toString(ints));
}
private static int[] countingSort(int[] arr) {
int max = arr[0];
int min = arr[0];
//step1:得到最大值和最小值,确定构建的数组长度
for (int value : arr) {
if (value > max) {
max = value;
}
if (value < min) {
min = value;
}
}
//step2:构建一个数组,用来存放每一个数对应出现的次数
int d = max - min;
int[] countArray = new int[d + 1];
//统计次数
for (int value : arr) {
countArray[value - min]++;
}
//step3:对此时的数组做变形,统计数组从第二个元素开始,每一个元素等于它本身都加上前面所有元素之和。
for (int i = 1; i < countArray.length; i++) {
countArray[i] += countArray[i - 1];
}
//step4:倒序遍历原始数列,从统计数组找到正确位置,输出到结果数组,确保稳定性
int[] sortedArray = new int[arr.length];
for (int i = arr.length - 1; i >= 0; i--) {
sortedArray[countArray[arr[i] - min] - 1] = arr[i];
countArray[arr[i] - min]--;
}
return sortedArray;
}
}
1.4分析
最佳情况:T(n) = O(n+k) 最差情况:T(n) = O(n+k) 平均情况:T(n) = O(n+k) 但是在数值很大的时候需要很大的空间