当前位置:   article > 正文

深入浅出排序算法之计数排序

深入浅出排序算法之计数排序

目录

1. 原理

2. 代码实现

3. 性能分析


1. 原理

首先看一个题目,有n个数,取值范围是 0~n,写出一个排序算法,要求时间复杂度和空间复杂度都是O(n)的。

为了达到这种效果,这一篇将会介绍一种不基于比较的排序方法。这种方法被称为计数排序。

计数排序的思路是这样的,对于每一个待排序元素a,如果知道了待排序数组中有多少个比它小的数,那么就可以直接知道在排序后的数组中 a 应该在什么位置上。比如,如果一个数组中有3个数是比a小的,那么,在排序后的数组里,a必然会出现在第4位。

现在问题转化成,对于待排序数组里的一个数,如何能快速知道比它小的数字有多少个。要解决这个问题,我们不能使用比较的办法,那样时间复杂度是无法降下来,只有换一个思路,以空间换时间。因为n个数的取值范围是 0~n,所以,不妨使用一个大小为 n 的数组来统计从0到n,每个数在待排序数组中出现的次数。这个数组类似于直方图数组,因为这种方式也被称做是基于统计的排序。直方图统计的思路简单清晰,在很多题目中都会有出现,一定要熟练掌握这种技巧。

强调:计数排序适合排序一组集中的数据。

2. 代码实现

  1. //计数排序
  2. public static void countSort(int[] array) {
  3. //1. 找到待排序数组的范围,也就是找到最大值和最小值
  4. int max = array[0];
  5. int min = array[0];
  6. //循环遍历找寻最小值和最大值
  7. for (int i = 1; i < array.length; i++) {
  8. if (array[i] > max)
  9. max = array[i];
  10. if (array[i] < min)
  11. min = array[i];
  12. }
  13. //计算待排数组的长度
  14. int len = max - min + 1;
  15. //2. 定义一个计数数组
  16. int[] count = new int[len];
  17. //3. 遍历array数组,把数据计数到计数数组中
  18. for (int i = 0; i < array.length; i++) {
  19. count[array[i] - min]++;
  20. }
  21. //4. 将array数组还原
  22. int index = 0;//来控制array数组的下标
  23. for (int i = 0; i < array.length; i++) {
  24. //这个循环的作用,是把count里面标记的数据取出来
  25. while (count[i] > 0) {
  26. array[index] = i + min;
  27. index++;
  28. count[i]--;
  29. }
  30. }
  31. }
  32. public static void main(String[] args) {
  33. int[] a = {5,4,3,2,1};
  34. Sort.countSort(a);
  35. for (int x : a) {
  36. System.out.print(x + " ");
  37. }
  38. }

3. 性能分析

时间复杂度空间复杂度
O(MAN(N,范围))O(N)
对数据的范围敏感对数据的范围敏感

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

闽ICP备14008679号