计数排序是一个非基于比较的线性时间排序算法,是一种稳定排序的算法。它的基本思想是对于给定的输入序列中的每一个元素 x,确定该序列中值小于 x 的元素的个数。一旦确定了这一信息,就可以将 x 直接存放到最终的输出序列的正确位置上。例如,如果输入序列中只有 9 个元素的值小于 x 的值,则 x 可以直接存放在输出序列的第 10 个位置上。当然,如果有多个元素具有相同的值时,我们不能将这些相同的元素放在输出序列的同一个位置上,因此还需对上述方案作适当的修改。
计数排序的步骤如下:
- 统计数组A中每个值A[i]出现的次数,存入C[A[i]];
- 从前向后,使数组C中的每个值等于其与前一项相加,C[A[i]]代表数组A中有多少个小于等于A[i]的元素;
- 反向填充目标数组B:将数组元素A[i]放在数组B的第C[A[i]]个位置(下标为C[A[i]] – 1),每放一个元素就将C[A[i]]递减。
在实现计数排序的过程中,我们需要两个辅助数组:B[0…n-1]存放排序结果,C[0…k-1]作为临时数组。(k为数组A中的最大值与最小值的极值差+1)
举个例子,以数组A = {4,,5,0,3,1,5,0,5}进行排序。流程如下:
代码:
public static int[] CountingSort(int[] a) {
int b[] = new int[a.length];
int max = a[0], min = a[0];
for (int i=1;i<a.length;i++) {
if (a[i] > max) {
max = a[i];
}
if (a[i] < min) {
min = a[i];
}
}
// k的大小是要排序的数组中,元素大小的极值差+1
int k = max - min + 1;
int c[] = new int[k];
//统计A数组元素出现次数
for (int i = 0; i < a.length; ++i) {
c[a[i] - min] += 1;
}
//更新计算C数组
for (int i = 1; i < c.length; ++i) {
c[i] = c[i] + c[i - 1];
}
//填充B数组
for (int i = a.length - 1; i >= 0; --i) {
b[--c[a[i] - min]] = a[i];
}
return b;
}