每天一点点之数据结构与算法 - 线性排序:计数排序(Counting sort)(未完待续)
个人觉得,记数排序其实是桶排序的一直特殊情况。
当要排序当数据是n,所处的数据范围不大的时候,最大值为k,我们就可以把数据划分为k个桶。每个桶内大数据都相同,省去了桶内快排的时间。
我们拿高考查分系统来说明。我们查分时,系统会现实我们的成绩以及所在省的排名。如果所在省有100万考生,如何通过成绩快速排序得出名次?
考生的满分是900分,最小是0分,这个数据范围很小,我们可以划分为901个桶,对应分数0-900分。根据考生成绩,我们将100万考生成绩划分到901个桶内。桶内的的数据都是分数相同的考生,所以并不需要再进行排序。因为只涉及到了扫描,所以时间复杂度是O(n)。
计数排序的思想就是这样,跟桶排序非常类似,只是桶的大小粒度不同。不过为什么要叫做计数呢?
我们还是拿考生那个例子来解释。为了理解方便,我们对数据进行简化。假设只有8个考生,分数在0-5分之间。我们把考生的成绩放在一个数组A[8]中。
A[8] = [2, 5, 3, 0, 2, 3, 0, 3]
考生的成绩0-5分,我们使用C[6]来表是桶,其中下标对应分数。不过,C[6]存储的不是考生成绩,而是对应的考生个数。例如:下标为0标示成绩为0的考生有2个,下标为1标示成绩为1的考生有0个,以此类推。
C[6] = [2, 0, 2, 3, 0, 1]
可以看出,分数为3分的考生有3个,小于3分的考生有4个,所以,成绩为3的考生在排序之后的有序数组R[8]中,会保存在下标为4,5,6的位置。
那么如何计算出,剋个分数的考生在有序数组中对应的存储位置呢?
思路是这样的:我们对C[6]数组顺序求和,C[6]存储的数据就变成下面数组(C[6] = [2, 2, 4, 7, 7, 8])。C[k]里存储小于等于分数k的考生个数。