计数排序法:用一个数组从小到大记录数组中相应大小数的次数,然后遍历这个数组记录的次数排序。
91 | 95 | 99 | 94 | 96 | 91 | 92 | 93 |
1. 创建一个数组记录相应数字出现次数的数组;
数组的大小 = 最大数字 -最小数字 +1; size = 99 - 91 + 1 = 9;
2. 遍历数组,用新数组记录次数;(用最小的数 91,作为偏移量)
91 - 91 = 0;(坐标 0 的值 +1)
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
95 - 91 = 4; (坐标 4 的值 +1)
1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
99 - 91 = 8;
1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 |
94 - 91 = 3;
1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |
96 - 91 = 5;
1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 |
91 - 91 = 0;
2 | 0 | 0 | 1 | 1 | 1 | 0 | 1 |
92 - 91 = 1;
2 | 1 | 0 | 1 | 1 | 1 | 0 | 1 |
93 - 91 = 2;
2 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
3. 然后,遍历这个新数组。坐标的值是多少,就输出几次值。
值 = 最小值 + 坐标;
0 坐标 2: 输出2次值, 值=最小值 + 坐标 = 91 + 0 = 91;
91 | 91 |
1 坐标 1: 输出1次值, 值=91 + 1 = 92;
91 | 91 | 92 |
...
91 | 91 | 92 | 93 | 94 | 95 | 96 | 99 |
代码如下:
//计数法
private int[] countSort(int arry[]) {
//数组的最大值和最小值
int min = arry[0], max = arry[0];
for (int i = 0; i < arry.length; i++) {
if (arry[i] > max) {
max = arry[i];
}
if (arry[i] < min) {
min = arry[i];
}
}
//数组的计数
int size = max - min + 1;
int[] arryCount = new int[size];
for (int i = 0; i < arry.length; i++) {
arryCount[arry[i] - min]++;
}
//排序
int size1 = 0;
int[] sortedArray = new int[arry.length];
for (int i = 0; i < arryCount.length; i++) {
for (int j = 0; j < arryCount[i]; j++) {
arry[size1] = min + i;
size1++;
}
}
return sortedArray;
}
优点:不需要相邻的两个值互相比较,时间复杂度较小;
缺点:1. 只适合最大值和最小值差值小的数组 ,差值太大浪费太大;
2. 只适合整数,如果是小数,数组的坐标是整数,不适合记录。