📜  计数排序 C++ (1)

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

计数排序 C++

计数排序 (Counting Sort) 是一种线性排序 (Linear Sorting) 算法,适用于数据范围较小的场景。它不是基于比较的排序算法,而是通过计算每个元素出现次数以确定元素在排序后序列中的位置。

算法思路

计数排序的基本思想是对于给定的输入序列中的每一个元素 x,确定该序列中值小于 x 的元素的个数,利用这一信息得到元素 x 在输出序列中的位置。

具体来说,计数排序包含以下步骤:

  1. 统计每个整数 i 在序列中出现的次数,存入长度为 k 的桶 (Bucket) 数组中。
  2. 对桶数组进行顺序求和,得到每个整数 i 在排序后序列中的位置。
  3. 从后往前依次遍历输入序列,根据每个元素的值以及桶数组中对应的值确定该元素在排序后序列中的位置,并将其存储在输出序列中。
  4. 完成排序。
复杂度分析

计数排序的时间复杂度为 $O(n+k)$,其中 n 表示输入序列的长度,k 表示序列中不同元素的个数。当 k 不大于 nlogn 时,计数排序比基于比较的排序算法的时间复杂度更低。

需要注意的是,计数排序的空间复杂度为 $O(k)$,当 k 相对于 n 来说很大时,计数排序并不适用。

C++ 实现

下面是使用 C++ 实现计数排序的代码:

void countingSort(vector<int>& nums) {
    // 确定序列中元素的取值范围
    int minVal = *min_element(nums.begin(), nums.end());
    int maxVal = *max_element(nums.begin(), nums.end());
    int k = maxVal - minVal + 1;

    // 统计序列中每个元素出现的次数
    vector<int> count(k, 0);
    for (auto num : nums) {
        count[num - minVal]++;
    }

    // 对桶数组进行顺序求和
    for (int i = 1; i < k; i++) {
        count[i] += count[i - 1];
    }

    // 从后往前依次遍历输入序列
    vector<int> res(nums.size());
    for (int i = nums.size() - 1; i >= 0; i--) {
        int pos = count[nums[i] - minVal] - 1;
        res[pos] = nums[i];
        count[nums[i] - minVal]--;
    }

    // 将排序后的结果赋值给原始序列
    nums = res;
}

在上述代码中,使用了 STL 库中的 min_element 和 max_element 函数分别计算序列中的最小值和最大值。接着,使用一个长度为 k 的桶数组统计序列中每个元素出现的次数。然后对桶数组进行顺序求和,得到每个元素在排序后序列中的位置。最后从后往前依次遍历输入序列,根据每个元素的值及桶数组中对应的值确定该元素在排序后序列中的位置,并将其存储在输出序列中。