Bootstrap

排序算法——计数排序

计数排序

计数排序 是一种线性时间复杂度的算法
按照理论分析,基于比较的排序算法,时间复杂度的下限是 O ( n ln ⁡ n ) O(n\ln n) O(nlnn)
虽然我也不知道怎么分析出来的,但是确实,不论是快速排序、归并排序、堆排序,它们的时间复杂度都是 O ( n ln ⁡ n ) O(n\ln n) O(nlnn)

但是有这么一种算法,它牺牲了空间来换取时间,得到了线性的时间复杂度
与低时间复杂度相对应的,是它的空间复杂度,达到了 O ( K ) O(K) O(K)
其中 K K K是数据范围

这就是计数排序

计数排序的主要原理是:
记录该数字出现的频率,然后直接输出

具体意思十分容易理解:
假设现在有这么一个数据:

5 5 2 2 3 1 0

其中52出现了两次、310都出现了一次
那么我构建这么一个数组,数组下标就是数据的大小,数组的大小就是数据的频次,然后将这个数据从小大到大输出
例如上面的数组就能写成

1 1 2 1 2

的形式

按照这种方式,只需要两次遍历即可完成排序:第一次遍历记录数据出现频次,第二次遍历将其输出
真正的线性时间复杂度

缺点是,它的空间复杂度和数据范围成正比
当数据范围小的时候,空间复杂度也很小
当数据范围大的时候,它会占用大量的空间

除此之外,它还有另外的缺点:
由于不是基于比较的排序算法,计数排序无法对负数和小数完成排序
当然,负数通过增加一定的偏移量可以解决
当数据规模小而数据范围大的时候,它的空间代价无法让人接受,而且其速度退化到比 O ( n ln ⁡ n ) O(n\ln n) O(nln

;