09. 排序算法-线性算法(Java语言实现)
上两节中,我带你着重分析了几种常用排序算法的原理、时间复杂度、空间复杂度、稳定性等。今天,我会讲三种时间复杂度是 的排序算法:桶排序、计数排序、基数排序。因为这些排序算法的时间复杂度是线性的,所以我们把这类排序算法叫作线性排序(Linear sort)。之所以能做到线性的时间复杂度,主要原因是,这三个算法是非基于比较的排序算法,都不涉及元素之间的比较操作。
按照惯例,我先给你出一道思考题:如何根据年龄给 100 万用户排序? 你可能会说,我用上一节课讲的归并、快排就可以搞定啊!是的,它们也可以完成功能,但是时间复杂度最低也是 O(nlogn)。有没有更快的排序方法呢?让我们一起进入今天的内容!
桶排序(Bucket sort)
首先,我们来看桶排序。桶排序,顾名思义,会用到“桶”,核心思想是将要排序的数据分到几个有序的桶里,每个桶里的数据再单独进行排序。桶内排完序之后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。
桶排序的时间复杂度为什么是 呢?我们一块儿来分析一下。
如果要排序的数据有 n 个,尽量做到将它们均匀地划分到 m 个桶内,每个桶里就有 k=n/m 个元素。我们会基于某种映射函数f ,将待排序列的元素 映射到[1, m]范围类的第i个桶中,下标则为[0, m - 1]。