计数排序(Counting Sort)是一种非比较排序算法,其时间复杂度为 O(n + k),适用于范围较小的整数排序。它通过计算每个元素在数组中出现的次数来确定每个元素的位置,从而实现排序。
public class CountingSort {
// 计数排序主方法
public static void countingSort(int[] arr) {
if (arr == null || arr.length == 0) {
return;
}
// 找出数组中的最大值和最小值
int max = arr[0];
int min = arr[0];
for (int num : arr) {
if (num > max) {
max = num;
}
if (num < min) {
min = num;
}
}
// 创建计数数组
int range = max - min + 1;
int[] count = new int[range];
// 计算每个元素出现的次数
for (int num : arr) {
count[num - min]++;
}
// 累加计数数组中的值
for (int i = 1; i < count.length; i++) {
count[i] += count[i - 1];
}
// 创建输出数组
int[] output = new int[arr.length];
// 将元素放入正确的位置
for (int i = arr.length - 1; i >= 0; i--) {
output[count[arr[i] - min] - 1] = arr[i];
count[arr[i] - min]--;
}
// 将排序后的数组复制回原数组
System.arraycopy(output, 0, arr, 0, arr.length);
}
// 打印数组
public static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
}
// 主方法
public static void main(String[] args) {
int[] arr1 = {4, 2, 2, 8, 3, 3, 1};
int[] arr2 = {9, 4, 10, 8, 2, 4, 7, 3, 6};
System.out.println("Before Sorting:");
printArray(arr1);
countingSort(arr1);
System.out.println("After Sorting:");
printArray(arr1);
System.out.println("Before Sorting:");
printArray(arr2);
countingSort(arr2);
System.out.println("After Sorting:");
printArray(arr2);
}
}
示例1:简单整数数组排序
假设有一个简单的整数数组 [4, 2, 2, 8, 3, 3, 1]
,我们可以使用计数排序对其进行排序。
public class CountingSortExample1 {
public static void main(String[] args) {
int[] arr = {4, 2, 2, 8, 3, 3, 1};
System.out.println("Before Sorting:");
CountingSort.printArray(arr);
CountingSort.countingSort(arr);
System.out.println("After Sorting:");
CountingSort.printArray(arr);
}
}
结果输出:
Before Sorting:
4 2 2 8 3 3 1
After Sorting:
1 2 2 3 3 4 8
示例2:包含负数的数组排序
计数排序也可以处理包含负数的数组。假设有一个数组 [9, 4, 10, 8, 2, 4, 7, 3, 6]
,我们可以使用计数排序对其进行排序。
public class CountingSortExample2 {
public static void main(String[] args) {
int[] arr = {9, 4, 10, 8, 2, 4, 7, 3, 6};
System.out.println("Before Sorting:");
CountingSort.printArray(arr);
CountingSort.countingSort(arr);
System.out.println("After Sorting:");
CountingSort.printArray(arr);
}
}
结果输出:
Before Sorting:
9 4 10 8 2 4 7 3 6
After Sorting:
2 3 4 4 6 7 8 9 10
代码详细解释
-
初始化部分:
max
和min
用于记录数组中的最大值和最小值。range
计算出数组中元素的取值范围(即最大值与最小值之差加 1)。count
数组用于记录每个元素出现的次数。
-
统计元素出现次数:
- 遍历输入数组,对于每个元素,计算其在
count
数组中的对应位置,并将该位置的值加 1。
- 遍历输入数组,对于每个元素,计算其在
-
累加计数:
- 遍历
count
数组,对于每个元素,将其值加上前一个元素的值。这样,count
数组的每个元素都包含了其前面所有元素的总和。
- 遍历
-
排序:
- 从输入数组的最后一个元素开始,找到其在
count
数组中的位置,并将其放到output
数组的正确位置。 - 更新
count
数组,使其对应位置的值减 1。
- 从输入数组的最后一个元素开始,找到其在
-
复制回原数组:
- 将排序后的
output
数组复制回原始数组。
- 将排序后的