不知道为什么,突然编辑器不支持颜色丰富的intellij IDEA直接复制了,博主有点沮丧,因此我先用图片的形式展示并分析,然后在最后会将全部代码呈上
排序思想:在一个数组中,对于每一个数据,都统计有多少个数字小于它,就能反应出它当前所在的位置
比如 [0,1,1,2] 这个数组中,'0'就有0个元素小于它,'2'就有3个元素小于它,而对于'1',则有2个元素小于它.
从以下方面不断进步着:
- 基础代码
- 一次改进,将排序适配范围扩大
- 二次改进,更舒服的使用这个算法
- 全部代码
一.基础代码
二.一次改进,将排序适配范围扩大
在这里,将适配范围增加,但是遗憾的是依旧只能对正整数进行排序
三.二次改进,更舒服的使用这个算法
四.全部代码
package com.sort;
/**
* 计数排序
* 对于每一个数据,统计整个数组中有多少小于它的数,这样就可以确定它的位置.
* 比如 : 比它小的有17个,那么它就应该在第18位上
*/
public class CountingSort {
public static int[] countingSort_1(int[] arr) {
//找到整个数组中的最大值
int max = arr[0];
for (int anArr : arr) {
if (max < anArr) {
max = anArr;
}
}
int[] result = new int[arr.length]; //作为排序完成的数组
int[] temp = new int[max + 1]; //用于保存临时数据
// 这里将 temp 的下标作为待排数组中的数值,而它对应的元素作为这个数值在数组中的频数
for (int i = 0; i < arr.length; i++) {
temp[arr[i]] = temp[arr[i]] + 1;
}
// 更新 temp 数组,将它存储的元素表示为:有多少元素小于(或等于)当前下标的值
for (int i = 1; i <= max; i++) {
temp[i] += temp[i - 1];
}
//将结果输出到 result[] 中
for (int i = arr.length - 1; i >= 0; i--) {
result[temp[arr[i]] - 1] = arr[i];
temp[arr[i]] = temp[arr[i]] - 1;
}
return result;
}
/*改进1:
* 观察上述代码,很明显能得到,上面真正能够执行的情况仅能排序的区间是 [ 1 , max ]
* 局限性很大,因此这里进行改进
* 改进后的排序算法可以排序的区间是 [ min , max ]
*/
//传递进来两个参数,说明排序区间为 [ min , max ]
public static int[] countingSort_2(int[] arr, int min, int max) {
//已经得到了整个数组中的最大值 max
int[] result = new int[arr.length]; //作为排序完成的数组
int[] temp = new int[max - min + 1]; //用于保存临时数据
// 这里将 temp 的下标作为待排数组中的数值,而它对应的元素作为这个数值在数组中的频数
for (int i = 0; i < arr.length; i++) {
temp[arr[i] - min] = temp[arr[i] - min] + 1;
}
// 更新 temp 数组,将它存储的元素表示为:有多少元素小于(或等于)当前下标的值
for (int i = 1; i <= max - min; i++) {
temp[i] += temp[i - 1];
}
//将结果输出到 result[] 中
for (int i = arr.length - 1; i >= 0; i--) {
result[temp[arr[i] - min] - 1] = arr[i];
temp[arr[i] - min] = temp[arr[i] - min] - 1;
}
return result;
}
/*改进2:
* 这次改进的不是代码本身,而是操作习惯.
* 一般而言,当我想调用一个数组对他进行排序的时候,通常不会而且不想知道它的最小值和最大值,
* 因此找到最小值和最大值的这一步需要我们用代码实现
*
* 改进之后,可以直接传入数组进行排序
*/
public static int[] countingSort_3(int[] arr) {
int min = arr[0], max = arr[0];
for (int anArr : arr) {
if (anArr > max) {
max = anArr;
} else if (anArr < min) {
min = anArr;
}
}
return countingSort_2(arr, min, max);
}
}