参考:https://www.cnblogs.com/onepixel/articles/7674659.html
其他排序算法传送门:https://blog.youkuaiyun.com/jkdcoach/article/details/87442482
源码:https://github.com/sunrui849/sort
计数排序
计数排序不是基于比较的排序算法,其核心在于将输入的数据值转化为键存储在额外开辟的数组空间中。 作为一种线性时间复杂度的排序,计数排序要求输入的数据必须是有确定范围的整数。
1.1 算法描述
- 找出待排序的数组中最大和最小的元素;
- 统计数组中每个值为i的元素出现的次数,存入数组C的第i项;
- 对所有的计数累加(从C中的第一个元素开始,每一项和前一项相加);
- 反向填充目标数组:将每个元素i放在新数组的第C(i)项,每放一个元素就将C(i)减去1。
1.2 动图演示
1.3特性
计数排序需要额外的空间来保存计数的信息,并且数是有范围的,范围比较小的时候还挺有效的
1.4代码实现
/**
* 从小到大
* 计数排序
* 假设知道最大值,最小值为0(如果不知道的话,通过计算需要比较 2*n 次,在计算时间复杂度的时候可以忽略常数)
* @param arr
* @return
*/
public static int[] sort(int[] arr) {
if (arr == null || arr.length == 0){
return arr;
}
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
for (int value : arr) {
max = Math.max(max,value);
min = Math.min(min,value);
}
int num = max - min +1;
int[] newArr = new int[num];
//开始计数
for (int value : arr){
newArr[value - min]++; //value - min 是将最小数放到数组0位置,以此类推
}
int index = 0;
//更新arr的值
for (int i = 0;i < num; i++) {
while (newArr[i] > 0){
arr[index++] = i + min;// i + min 还原真实数据
newArr[i]--;
}
}
return arr;
}