# 13 如何根据年龄给100万用户数据排序

三种时间复杂度是O(n)的排序算法:桶排序、计数排序、基数排序。因为这些排序算法的时间复杂度是线性的,所以我们把这类排序算法叫做线性排序。之所以能做到线性的时间复杂度,主要原因是,这三个算法是非基于比较的排序算法,都不涉及元素之间的比较操作。

重点掌握这些排序算法的适用场景

桶排序(Bucket sort)

顾名思义,会用到”桶“,核心思想是将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序。桶内排序后,再把每个桶里的数据一次取出,组成的序列就是有序的了。

桶排序的时间复杂度是O(n) 分析
如果要排序的数据有n个,我们把他们均匀地划分到m个桶内,每个桶内就有k=n/m个元素。每个桶内部使用快速排序,时间复杂度是O(k*logk)。m个桶排序的时间复杂度就是O(m*k*logk)。因为k=n/m,所以整个桶排序的时间复杂度就是O(n*log(n/m))。当桶的个数接近个数n时,log(n/m)就是一个非常小的常量,这个时候桶排序时间复杂度接近O(n).

桶排序看起来很优秀,那它是否可以替代我们之前的排序算法呢

答案是否定的,实际上,桶排序对排序数据的要求是非常苛刻的。

首先,要排序的数据需要很容易就能划分成n个桶,并且,桶与桶之间有着天然的大小顺序。这样每个桶内的数据排序后,桶与桶之间的数据不需要再进行排序。

再次,数据再各个桶之间的分布是比较均匀的。如果数据经过划分之后,有些桶里的数据非常多,有些非常少,很不均匀,那桶内数据排序的时间复杂度就不是常量级了。在极端情况下,如果数据都被划分到一个桶里,那就退化到O(nlogn)的排序算法了

计数排序(Counting sort)

计数排序可以看做桶排序的一种特殊情况。当要排序的n个数据,所处的范围并不大的时候,比如最大值k,可以把数据划分成k个桶。每个桶内的数据值都是相同的,省掉了桶内排序的时间

计数排序的算法思想就是这么简单,跟桶排序非常类似,只是桶的大小粒度不一样。

总结:计数排序只能用在数据范围不大的场景中,如果数据范围k比要排序的数据n大很多,就不适合用计数排序了。

基数排序(Radix sort)

基数排序对要排序的数据是由要求的,需要分割出独立的位来比较,而且位之间有递进的关系,如果a数据的高位比b数据大,那生剩下的低位就不用比较了。除此之外,每一位数据范围不能太大,要可以用线性排序算法来排序,否则,基数排序的时间复杂度就无法做到O(n)了。

你可能感兴趣的:(# 13 如何根据年龄给100万用户数据排序)