前面所讲的排序都需要进行比较才能排序------比较类型的排序算法
计数排序
场景:数据局密集,几种在某个范围中
时间复杂度:O(N) , N:表示区间中元素的个数
空间复杂度:O(M) ,M: 表示区间中元素种类的个数
稳定性:稳定
思路:
(1).开一个长度为 maxValue-minValue+1 的数组,然后分配。扫描一遍原始数组,以当前值- minValue 作为下标,将该下标的计数器增1。
(2).收集。扫描一遍计数器数组,按顺序把值收集起来。
举个例子, nums=[2, 1, 3, 1, 5] , 首先扫描一遍获取最小值和最大值,
maxValue=5 , minValue=1 ,于是开一个长度为5的计数器数组 counter ,
- 分配。统计每个元素出现的频率,得到 counter=[2, 1, 1, 0, 1] ,例如 counter[0] 表示值 0+minValue=1 出现了2次。
- 收集。 counter[0]=2 表示 1 出现了两次,那就向原始数组写入两个1,
- counter[1]=1 表示 2 出现了1次,那就向原始数组写入一个2,依次类推,最终原始数组变为 [1,1,2,3,5] ,排序好了。
计数排序本质上是一种特殊的桶排序,当桶的个数最大的时候,就是计数排序。
实现代码:
public static void countSort(int[] array){
//1.统计元素的范围
int min=array[0];
int max=array[0];
for (int i=1;i<array.length;i++){
if(array[i]>max){
max=array[i];
}
if(array[i]<min){
min=array[i];
}
}
//2.开辟计数的空间
//该范围中最多包含不同元素的个数
int range=max-min+1;
int[] arrayCount=new int[range];
//3.统计每个元素出现的个数
for (int i=0;i<array.length;i++){
arrayCount[array[i]-min]++;
}
//4.对元素进行回收--排序
int index=0;
for(int i=0;i<range;i++){
while (arrayCount[i]--!=0){
array[index++]=i+min;
}
}
}