参考文章:
https://www.cnblogs.com/freedom314/p/5847092.html 计数排序详解(强推)
https://www.cnblogs.com/guoyaohua/p/8600214.html 十大经典排序算法最强总结(含JAVA代码实现)
计数排序分析:
平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
O(n+k) | O(n+k) | O(n+k) | O(k) | Out-place | 稳定 |
温馨提示:
上面的这篇博客,确实对 计数排序 的原理做了很好的解释,如果理解了原理之后,其实很快的就可以用 Java 写出 计数排序的例子。若干看不懂代码,记得拿出纸和笔,按照程序走一遍,走一遍,再走一遍!!!
计数排序原理:
计数排序的核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
计数排序(Counting sort)是一种稳定的排序算法。计数排序使用一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数。然后根据数组C来将A中的元素排到正确的位置。它只能对整数进行排序。
计算排序算法描述:
- 找出待排序的数组中最大和最小的元素;
- 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
- 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
- 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
计数排序算法图解原理:
Java 代码实现计数排序算法:
代码一
package com.sorting.algorithm;
public class CountingSort {
public static int[] countSort(int[] array){
// 1, 计数排序 如数组 { 7 4 2 1 5 3 1 5 },比7小的元素有7个,7就应该排在第八位,同理,1在第一位或者第二位
int[] arrA = array;
int max = arrA[0];
for (int i = 0; i < arrA.length; i++) {
if(arrA[i] > max)
max = arrA[i];
}
int[] arrB = new int[max+1];
int[] arrC = new int[arrA.length];
// 2,统计数组中元素出现的个数,按照大小进行排序,
for (int i = 0; i < arrA.length; i++) {
arrB[arrA[i]]++;
}
for (int i = 1; i < arrB.length; i++) {
arrB[i] = arrB[i] + arrB[i-1];
}
// 3, 根据元素在数组中出现的个数,对元素进行排序,
for (int i = 0; i < arrC.length; i++) {
arrB[arrA[i]]--;
arrC[arrB[arrA[i]]] = arrA[i];
}
return arrC;
}
public static void printArr(int[] array){
for (int i = 0; i < array.length; i++) {
if(i != array.length)
System.out.print(array[i]+ ", ");
}
System.out.println();
}
public static void main(String[] args) {
int[] array = {7,4,2,1,5,3,1,5};
System.out.println("排序之前:");
printArr(array);
int[] sortedArr = countSort(array);
System.out.println("排序之后:");
printArr(sortedArr);
}
}
代码二:
package com.sorting.algorithm;
import java.util.Arrays;
public class CountingSort2 {
public static int[] countSort(int[] array){
int bias,max=array[0],min=array[0];
for (int i = 0; i < array.length; i++) {
if(max < array[i])
max = array[i];
if(min > array[i])
min = array[i];
}
// 数组中最小元素到0 的偏离程度
bias = 0-min;
// 辅助数组的大小设为 max-min+1 ,
int[] bucket = new int[max-min+1];
// 将 bucket 每个数组元素设置为0
Arrays.fill(bucket, 0);
// 统计原数组中每个元素出现的次数
for (int i = 0; i < array.length; i++) {
bucket[array[i]+bias]++;
}
// 设置两个参数 index 和 i,分别指向 array 和 bucket 的下标,依次往后走,
int index=0 , i=0;
while(index < array.length){
if(bucket[i]!=0){
array[index] = i-bias;
bucket[i]--;
index++;
}else {
i++;
}
}
return array;
}
public static void printArr(int[] array){
for (int i = 0; i < array.length; i++) {
if(i != array.length)
System.out.print(array[i]+ ", ");
}
System.out.println();
}
public static void main(String[] args) {
int[] array = {7,4,2,1,5,3,1,5};
System.out.println("排序之前:");
printArr(array);
int[] sortedArr = countSort(array);
System.out.println("排序之后:");
printArr(sortedArr);
}
}
计数排序代码测试:
代码一:
代码二:
上面的代码都经过我的测试,大家如果有疑问,也可以留言。