当前位置:   article > 正文

经典排序算法之计数排序|c++代码实现_频次排序c++

频次排序c++

 引言

排序算法c++实现系列第8弹——计数排序

计数排序是理解起来相对简单的一个排序算法,

计数排序

计数排序(Counting Sort)是一种非比较型的排序算法,它的基本思想是统计待排序数组中每个元素的出现次数,然后根据统计信息将元素放置到正确的位置上,从而实现排序。计数排序适用于排序范围不大的非负整数数组,并且可以在线性时间内完成排序。

算法步骤

  1. 确定数据范围:寻找数据中的最大值和最小值。

  2. 统计频次:遍历待排序数组,统计每个元素出现的次数,并将统计结果存储在一个辅助数组(计数数组)中。

  3. 累加频次:对计数数组进行顺序累加,方便后续排序操作中得到原数组中每个数的下标位置。

  4. 排序:遍历待排序数组,根据元素的值和计数数组的统计信息,将元素放置到正确的位置上。

  5. 输出:将排序后的数组输出,排序完成。

算法的核心步骤如上,仅看步骤可能还是难以理解,可以联系着代码一起看。这边也推荐一个我个人觉得会让算法不那么抽象的学习方法:当在学习某一算法时,可以先去b站搜该算法的简单动图演示,大概了解步骤后,再来看以上的步骤总结和代码实现,事半功倍。

这里借助一个实实在在的例子,向大家演示计数排序算法:假设有 a[] = {1,2,3,5,6,7,3};

  1. 寻找最大值max=7;最小值min=1。

  2. 创建一个新数组b作为计数数组,将a遍历统计每个数据出现的频次。

  1. for (int i = 0; i < len; i++) {
  2. a[arr[i] - min]++; //arr[i] - min即将输入的数据值转化为的键
  3. }
  4. // 如 a[arr[0]-min] = a[1-1] => a[0] = 1;
  5. // a[arr[1]-min] = a[2-1] => a[1] = 1;

特点

  • 计数排序是一种稳定的排序算法,相同元素的相对位置在排序后保持不变。

  • 计数排序的时间复杂度为O(n+k),其中 n 为待排序数组的长度,k为待排序数组中的最大值与最小值之差加一。

  • 计数排序适用于待排序数组元素范围不大的情况,如果待排序数组范围较大,计数数组的空间消耗会增加。

代码

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int main() {
  4. int max = INT_MIN, min = INT_MAX;
  5. int arr[] = {61, 17, 29, 22, 34, 60, 72, 21, 50, 1, 62};
  6. int len = (int) sizeof(arr) / sizeof(*arr);
  7. // 寻找数组的max和min,以便建立计数数组
  8. for (int i = 0; i < len; i++) {
  9. max = max < arr[i] ? arr[i] : max;
  10. min = min > arr[i] ? arr[i] : min;
  11. }
  12. // printf("max:%d,min:%d\n", max, min);
  13. int d = max - min + 1; // 计数数组长度
  14. int a[d] = {0}; // 计数数组
  15. for (int i = 0; i < len; i++) {
  16. a[arr[i] - min]++;
  17. }
  18. for (int i = 1; i < d; i++) {
  19. a[i] += a[i - 1]; // 对次数累加,方便后续得到每个数的index
  20. }
  21. int b[len] = {0}; // b[]存放排序后的数组
  22. for (int i = len - 1; i >= 0; i--) {// 从后往前排序-->稳定排序算法
  23. int index = a[arr[i] - min] - 1; // 遍历a[]中每一个数,确定其index
  24. b[index] = arr[i];
  25. a[arr[i] - min]--;
  26. }
  27. for (int i = 0; i < len; i++) {
  28. arr[i] = b[i];
  29. printf("%d ", arr[i]);
  30. }
  31. return 0;
  32. }

运行结果展示

系列其他文章

十大经典排序算法复杂度、应用场景总结 | 插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序、桶排序、计数排序-CSDN博客 

经典排序算法之桶排序详解|c++代码实现|简单易懂-CSDN博客

经典排序算法之基数排序详解|c++代码实现|简单易懂-CSDN博客

经典排序算法之堆排序详解|c++代码实现|什么是堆排序|如何代码实现堆排序-CSDN博客

经典排序算法之快速排序|c++代码实现|什么是快速排序|如何代码实现快速排序-CSDN博客

经典排序算法之归并排序|递归和迭代法代码均提供|c++代码实现|什么是归并排序|如何代码实现-CSDN博客

经典排序算法之希尔排序|c++代码实现||什么是希尔排序|如何代码实现-CSDN博客

经典排序算法之插入排序|c++实现|什么是插入排序|如何代码实现-CSDN博客

排序算法之选择排序|c++实现-CSDN博客

经典排序算法之冒泡排序|c++代码实现-CSDN博客

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/913070
推荐阅读
相关标签
  

闽ICP备14008679号