* 计数排序
* 排序流程:
1.找出源数组中的最小值;
2.找出源数组中的最大值;
3.创建=最大值+1长度的新数组;
4.在新数组中循环从最小值开始;
5.再次循环源数组,直接将值作为新数组的下标;
6.相同的数字,出现一次,就在对应的下标位置上+1;
7.遍历新数组,新数组中下标值为0的跳过,有值的直接的输出当前下标(当前下标便是需要排序的数字);
8.下标的值为X,就输出X次。
9.依次放入最终的结果集数组中。
* 适用场景:
适用于数据范围相对较小的情况。若范围太大,需要创建一个很长的数组来装填,就浪费了很多空间;
排序代码如下,直接运行看结果吧,比较简单,就没必要赘述了。
/**
* 计数排序
* @author chengxp
*/
public class Counting {
/**
* 排序入口
*
* @param arr
*/
public static void entry(int[] arr) {
int min = arr[0];
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
//找出最小值
if (min > arr[i]) {
min = arr[i];
}
//找出最大值
if (max < arr[i]) {
max = arr[i];
}
}
System.out.println("min value:" + min);
System.out.println("max value:" + max);
// 构建一个新的数组,把原数组中数据的值当作下标存入,下标从0开始;因为max要放入对应下标中,所以要+1
int[] bucketArr = new int[max + 1];
for (int k = 0; k < arr.length; k++) {
//数字每出现一次,就在原基础上+1
bucketArr[arr[k]] = bucketArr[arr[k]] + 1;
}
//输出最终结果
int finalIndex = 0;
for (int h = min; h < bucketArr.length; h++) {
if (bucketArr[h] > 0) {
//下标为l,就代表有l个数字
for (int l = 0; l < bucketArr[h]; l++) {
arr[finalIndex++] = h;
}
}
}
}
public static void main(String[] args) {
int[] arr = DataProvider.getRandomArray(13);
System.out.println("source arr:" + Arrays.toString(arr));
Counting.entry(arr);
System.out.println("res arr:" + Arrays.toString(arr));
}
}
输出结果:
source arr:[87, 62, 75, 20, 78, 0, 24, 21, 33, 31, 81, 15, 20]
min value:0
max value:87
res arr:[0, 15, 20, 20, 21, 24, 31, 33, 62, 75, 78, 81, 87]