![6b07e05b178fea2d20429304594fbb07.png](https://i-blog.csdnimg.cn/blog_migrate/ed0b80fffc249e0905b02d2b6ccfc3f5.jpeg)
时空权衡
在前面的章节里,我们知道归并排序是一种高效的排序算法,在任何情况下时间复杂度都为
![fcdc316654d9fa870000610479fffa7d.png](https://i-blog.csdnimg.cn/blog_migrate/a1100d082551c94011d23849c044693a.jpeg)
在通常情况下,我们都认为时间更宝贵,而空间相对廉价。因此在大多数情况下,我们都是以牺牲空间的方式来减少运行时间。
计数排序
计数排序(counting sort)就是一种牺牲内存空间来换取低时间复杂度的排序算法,同时它也是一种不基于比较的算法。这里的不基于比较指的是数组元素之间不存在比较大小的排序算法,我们知道,用分治法来解决排序问题最快也只能使算法的时间复杂度接近
下面我们就来介绍一种不基于比较的排序算法:计数排序。我们用一种通俗方式来理解这个过程过程。如下图所示,假设我们用不同大小的小球来表示每一个数组元素的值,我们的目标是使小球从小到大以次排列。
![045c1e5ee8e93371fa10af2924936084.png](https://i-blog.csdnimg.cn/blog_migrate/41110f0ea8c163bdc1b97e37dca00e63.jpeg)
首先我们需要知道最大的球和最小的球分别对应的元素,这里最大的对应
![f87cab0757ba8730249206886f2a85b9.png](https://i-blog.csdnimg.cn/blog_migrate/0f4cd6f0088a2762ff51afea260dedfd.jpeg)
然后我们需要用
![c83a05e2576d22c1fa93b25a068ad658.png](https://i-blog.csdnimg.cn/blog_migrate/7eed554f0ed05b05bf380ca36c8a6e77.jpeg)
接下来,我们遍历所有的小球,将每个值为
![1dbaf629808966adf5adeb951d35e431.png](https://i-blog.csdnimg.cn/blog_migrate/268b12ffcc2ea9dbbc7b563cc000fad2.jpeg)
最后,我们从左往右依次将每个桶里的小球取出,每取出一个小球,对应桶的计数器减
![9e0506f68baa0edd6d547fa31b21eeea.png](https://i-blog.csdnimg.cn/blog_migrate/de916c530969c9e788d96bb2df2e5578.jpeg)
我们用一个动画来完整地看一看这个过程。
![821ab6187eb4d36c8f4250692f2a6246.png](https://i-blog.csdnimg.cn/blog_migrate/6a9f627cbd5b7ec9fd584f2749269f65.png)
代码实现:
def counting_sort(array):
largest = max(array); smallest = min(array) # 获取最大,最小值
counter = [0 for i in range(largest-smallest+1)] # 用于统计个数的空数组
idx = 0 # 桶内索引值
for i in range(len(array)):
counter[array[i]-smallest] += 1 # 统计每个元素出现的次数
for j in range(len(counter)):
while counter[j] > 0:
array[idx] = j + smallest # 取出元素
idx += 1
counter[j] -= 1
return array
整个过程需要遍历两次数组,一次是遍历长度为
我们可以看到计数排序突破了基于比较的排序算法效率的下界,达到了线性的复杂度,是到目前为止我们接触到的最快的算法。我们还是可以通过运行时间来间接反应这一结论,大家可以将下面的结果和前面复杂度为
>>> python "counting sort.py"
>>> 平均比较次数:0
平均运行时间:0.0172 s
→本节全部代码←
← 2-3 树 | 算法与复杂度zhuanlan.zhihu.com![a39433c575f64974e0d1060db754dbec.png](https://i-blog.csdnimg.cn/blog_migrate/a8a0bb7ba842ddfa50410e58b69d8a70.jpeg)
![a39433c575f64974e0d1060db754dbec.png](https://i-blog.csdnimg.cn/blog_migrate/a8a0bb7ba842ddfa50410e58b69d8a70.jpeg)