📜  计数排序java(1)

📅  最后修改于: 2023-12-03 15:27:57.361000             🧑  作者: Mango

计数排序

计数排序是一种非常快速的排序算法,它的核心思想在于统计每个元素出现的次数,然后根据这个统计结果将元素排好序。计数排序适用于数据范围比较小的情况,时间复杂度为$O(n+k)$,其中$n$为待排序序列长度,$k$为元素取值范围。

算法流程
  1. 统计每个元素出现的次数
  2. 统计各元素在待排序序列中的位置
  3. 将元素排好序
代码实现

以一个整型数组为例,代码如下:

public static int[] countingSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return arr;
    }
    int[] count = new int[10];
    for (int i = 0; i < arr.length; i++) {
        count[arr[i]]++;
    }
    for (int i = 1; i < count.length; i++) {
        count[i] += count[i - 1];
    }
    int[] res = new int[arr.length];
    for (int i = 0; i < arr.length; i++) {
        res[--count[arr[i]]] = arr[i];
    }
    return res;
}

上述代码实现了一个简单的计数排序算法,其中count数组用于统计每个数字出现的次数,res数组用于存放排序后的结果。时间复杂度为$O(n+k)$,空间复杂度为$O(k)$。

算法优化

在实际应用中,可以通过以下方式优化计数排序算法:

  1. 数组扩容:当元素取值范围$k$较大时,可以先统计元素出现次数,再按照次数创建一个新的数组。这样可以减小空间复杂度,同时也可以大幅减少时间复杂度。

  2. 两趟扫描:统计元素出现次数的过程可以分为多次遍历,减少数组扫描次数。

public static int[] countingSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return arr;
    }
    int max = arr[0];
    for (int i = 1; i < arr.length; i++) {
        max = Math.max(max, arr[i]);
    }
    int[] count = new int[max + 1];
    for (int i = 0; i < arr.length; i++) {
        count[arr[i]]++;
    }
    for (int i = 1; i < count.length; i++) {
        count[i] = count[i] + count[i - 1];
    }
    int[] res = new int[arr.length];
    for (int i = arr.length - 1; i >= 0; i--) {
        res[--count[arr[i]]] = arr[i];
    }
    return res;
}

上面的代码实现了一个优化版的计数排序算法,时间复杂度为$O(n+k)$,空间复杂度为$O(k)$。它避免了数组扫描次数过多的情况,同时也减小了空间复杂度。

算法应用

计数排序适用于数据范围比较小的情况,如桶排序、基数排序等算法的基础。在一些计算机视觉领域、排序算法等应用中,计数排序也被广泛地使用。