算法 | 复杂度与计数排序

Posted 爱好历史的程序员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法 | 复杂度与计数排序相关的知识,希望对你有一定的参考价值。

时间复杂度

设定算法操作执行次数为函数T(n),若存在函数f(n),使得n趋向于无穷大时,T(n)/f(n)的极限值为不等于0的常数,建成后f(n)是T(n)的通数量级函数,记作T(n)=O(f(n)),O为算法的渐进时间复杂度,简称时间复杂度。

计算原则:

  • 如果运行时间是常数量级,则用常数1表示。

  • 只保留时间函数的最高阶项

  • 如果最高阶项存在,则省去前面的系数

空间复杂度

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。S(n)=O(f(n))。

我们对之前文章七种排序列出的复杂度:

排序算法 平均时间复杂度 最坏时间复杂度 空间复杂度 是否稳定
冒泡排序 O(n2) O(n2) O(1)
插入排序 O(n2) O(n2) O(1)
选择排序 O(n2) O(n2) O(1) 不是
希尔排序 O(nlogn) O(ns) O(1) 不是
堆排序 O(nlogn) O(nlogn) O(1) 不是
归并排序 O(nlogn) O(nlogn) O(n)
快速排序 O(nlogn) O(n2)O(n2) O(logn) 不是

更多细节推荐文末第一篇文章。https://blog.csdn.net/yushiyi6453/article/details/76407640


另外再来介绍一种排序算法--计数排序。

假如有一系列数字90-100,现在排序。

 
   
   
 
  1. function sort()

  2. {

  3. $arr = [98, 96, 99, 90, 99, 92, 91, 94, 98, 96, 95];

  4. $min = $max = $arr[0];

  5. $count = count($arr);

  6. // 计算长度

  7. for ($i=1; $i < $count; $i++) {

  8. if ($arr[$i] > $max) {

  9. $max = $arr[$i];

  10. continue;

  11. }


  12. if ($arr[$i] < $min) {

  13. $min = $arr[$i];

  14. }

  15. }

  16. $length = $max - $min;


  17. for ($i=0; $i<=$length; $i++) {

  18. $countArr[$i] = 0;

  19. }


  20. //计数

  21. for ($i=0; $i<$count; $i++) {

  22. $countArr[$arr[$i] - $min]++;

  23. }


  24. //遍历回来

  25. foreach ($countArr as $k=>$v) {

  26. for ($j=0; $j<$v; $j++) {

  27. $result[] = $k+$min;

  28. }

  29. }


  30. return $result;

  31. }

可以看看gif图片:

算法 | 复杂度与计数排序

那么问题来了,假如这些数字是学生成绩,同分的我们也需要记下对应的人排名,那么怎么办呢?

我们可以在计数之后在进行依次遍历,在对应的下标增加进入前面下标的数量。

假定现在有:

 
   
   
 
  1. [92, 91, 90, 95, 94, 99, 97, 99, 91, 92]

红色是普通的计数,黄色的是进阶计数。

 
   
   
 
  1. function sort()

  2. {

  3. $arr = ['a' => 92, 'b' => 91, 'c' => 90, 'd' => 95, 'e' => 94, 'f' => 99,

  4. 'h' => 97, 'i' => 99, 'j' => 91, 'k'=>92];

  5. $min = $max = $arr['a'];

  6. $count = count($arr);

  7. // 计算长度

  8. foreach ($arr as $val) {

  9. if ($val > $max) {

  10. $max = $val;

  11. continue;

  12. }


  13. if ($val < $min) {

  14. $min = $val;

  15. }

  16. }

  17. $length = $max - $min;


  18. for ($i=0; $i<=$length; $i++) {

  19. $countArr[$i] = 0;

  20. }


  21. //计数

  22. foreach ($arr as $val) {

  23. $countArr[$val - $min]++;

  24. }

  25. // var_dump($countArr);

  26. for ($i=1; $i<=$length; $i++) {

  27. $countArr[$i] += $countArr[$i-1];

  28. }

  29. //遍历回来

  30. foreach ($arr as $k=>$val) {

  31. $result[$count + 1 - $countArr[$val - $min] - 1] = [$k, $val];

  32. $countArr[$val - $min]--;

  33. }


  34. return $result;

  35. }

计数排序适合排序有效区间内的整数,局限性比较多。




参考文章:

文中图片来自以下文章,如有版权问题,请告知删除。有兴趣也可以看下以下文章。

  • 排序算法时间复杂度、空间复杂度、稳定性比https://blog.csdn.net/yushiyi6453/article/details/76407640

  • 《漫画算法》@程序员小灰

  • 时间复杂度和空间复杂度-https://www.cnblogs.com/chenjinxinlove/p/10038919.html

  • 计数排序-https://www.jianshu.com/p/e9db78d3c93c

  • 计数排序--《程序员小灰》- https://www.cnblogs.com/easilyai/p/9769773.html

以上是关于算法 | 复杂度与计数排序的主要内容,如果未能解决你的问题,请参考以下文章

八大排序算法C语言过程图解+代码实现(插入,希尔,选择,堆排,冒泡,快排,归并,计数)

算法计数排序桶排序和基数排序详解

算法面试与实战-05排序算法- 时间复杂度为O(n)的排序算法(桶排序)

算法笔记_129:计数排序(Java)

十大经典排序算法总结(计数排序)

计数排序