计数排序适用于最大值和最小值产别不大的数组,如果说最小为0,最大为1亿,那么就需要创建容量为1亿个元素的数组,时间复杂度就很高了
把数组元素作为临时数组的下标,统计每个下表出现的次数,最后再从索引为0开始依次顺序遍历该临时数组,次数为n就输出n次,就排序好了
为什么要max - min + 1
?因为如果你属元素是90-100之间,按照``max + 1`你要创建大小为101的数组,这样很浪费空间,于是我们可以优化一下,创建最大元素和最小元素之差大小的容量,然后用min为增量,这样子只需要创建大小为10的数组即可,然后输出时候只需要索引下标加上min增量即可
时间复杂度为O(n+k)、空间复杂度为O(k)。n为待排序数组的大小,k为临时数组的大小。该排序是稳定排序,由于需要创建临时数组,所以是非原地排序
代码实现
import java.util.Arrays;
/**
* @Description: 计数排序
* @Author: LinZeLiang
* @Date: 2020-10-09
*/
public class CountSort {
public static void main(String[] args) {
int[] a = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
countSort(a);
System.out.println(Arrays.toString(a));
}
/**
* 计数排序
*
* @param a 待排序数组
*/
private static void countSort(int[] a) {
int min = a[0];
int max = a[0];
//找出最大值与最小值
for (int i = 0; i < a.length; i++) {
if (min > a[i]) {
min = a[i];
}
if (max < a[i]) {
max = a[i];
}
}
//创建临时计数数组
//根据最大值和最小是确定数组的长度
int[] arr = new int[max - min + 1];
//开始计数
for (int i = 0; i < a.length; i++) {
arr[a[i] - min]++;
}
//遍历统计的数组,替换掉原来的数组
int k = 0;
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i]; j++) {
a[k++] = i + min;
}
}
}
}
原文:https://www.cnblogs.com/linzedian/p/13789704.html