授课语音

计数排序法

1. 介绍

计数排序是一种非比较排序算法,它通过统计数据中每个元素出现的次数,然后根据这些统计信息将元素排成有序序列。与传统的基于比较的排序算法不同,计数排序不需要进行元素之间的直接比较,因此能够在特定条件下达到更高的排序效率。

1.1 计数排序的基本思想:

计数排序的基本思想是通过“计数”的方式来代替比较。它适用于数据范围比较小的情况。当数据范围不是很大时,计数排序的效率可能比常见的比较排序算法(如快速排序、归并排序)更高。计数排序的工作流程大致如下:

  1. 确定数据的范围:首先找出数据中的最大值和最小值,从而确定数据的取值范围。
  2. 创建计数数组:根据数据的取值范围,创建一个计数数组,用于统计每个数字出现的次数。
  3. 统计频次:遍历原始数组,根据每个元素的值在计数数组中进行计数。
  4. 生成排序数组:根据计数数组的统计结果,将元素按顺序放入输出数组,得到有序数组。

1.2 计数排序的适用条件:

  1. 数据的范围(最大值和最小值的差距)相对较小。
  2. 数据的分布较为均匀。
  3. 适用于整数排序或某些特定类型的排序(如字符排序)。

1.3 计数排序的时间复杂度:

  • 时间复杂度O(n + k),其中n是待排序元素的个数,k是数据范围的大小(最大值与最小值之差)。
  • 空间复杂度O(k),需要额外的空间来存储计数数组。

计数排序是一种稳定的排序算法。稳定的排序算法意味着相等元素的相对顺序在排序后不会改变,这对于某些应用场景(例如多重排序)非常有用。


2. 代码案例

下面是使用Java实现计数排序的示例代码:

import java.util.Arrays;

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 i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];  // 更新最大值
            }
            if (arr[i] < min) {
                min = arr[i];  // 更新最小值
            }
        }

        // 创建计数数组,大小为最大值与最小值之间的范围
        int[] count = new int[max - min + 1];

        // 统计每个元素的出现频率
        for (int i = 0; i < arr.length; i++) {
            count[arr[i] - min]++;
        }

        // 将计数数组中的元素按顺序放回原数组
        int index = 0;
        for (int i = 0; i < count.length; i++) {
            while (count[i] > 0) {
                arr[index++] = i + min;  // 将当前元素放回数组
                count[i]--;
            }
        }
    }

    public static void main(String[] args) {
        // 示例数组
        int[] arr = {4, 2, 2, 8, 3, 3, 1};

        // 输出排序前的数组
        System.out.println("排序前: " + Arrays.toString(arr));

        // 调用计数排序
        countingSort(arr);

        // 输出排序后的数组
        System.out.println("排序后: " + Arrays.toString(arr));
    }
}

2.1 代码解析:

  1. 初始化最大值和最小值: 我们首先遍历数组,找出其中的最大值和最小值。这一步是为了后续创建计数数组时,确定计数数组的大小。

  2. 创建计数数组: 根据最大值和最小值,创建一个计数数组。该数组的大小为max - min + 1,用于记录每个数出现的频率。

  3. 统计频率: 遍历原数组,对于每个元素,更新计数数组中对应位置的值。count[arr[i] - min]表示元素arr[i]出现的次数。

  4. 根据计数数组生成有序数组: 遍历计数数组,根据频率将每个元素依次放入原数组中,从而得到排序后的数组。


2.2 测试结果:

对于输入数组 {4, 2, 2, 8, 3, 3, 1},排序后的结果将是:

排序前: [4, 2, 2, 8, 3, 3, 1]
排序后: [1, 2, 2, 3, 3, 4, 8]

3. 总结

计数排序是一种基于计数的排序方法,通过统计每个元素的出现次数来实现排序。它适用于数据范围较小的情况,能够在某些场景下显著提高排序效率。需要注意的是,计数排序不能用于处理负数,并且数据范围较大时需要消耗较大的空间,因此它的适用场景有一定限制。在实际使用时,结合数据的特性来选择合适的排序算法非常重要。

  • 适用场景:数据范围小,元素分布均匀的情况。
  • 时间复杂度:O(n + k),其中n是元素个数,k是数据范围的大小。
  • 空间复杂度:O(k),需要额外的计数数组空间。

计数排序通过其高效的计数机制,在一些特定场景中能提供比比较排序更快的性能,但也有一些使用限制。了解这些特性后,能够在合适的场景下充分发挥计数排序的优势。

去1:1私密咨询

系列课程: