常见的排序算法,像归并排序,堆排序时间复杂度为O(nlgn);像冒泡排序,插入排序则为O(n^2)。对于排序算法而言,只要你是通过比较,O(nlgn)是一条难以逾越的界限。为了追求更快的速度,智慧的人类发明了一种新的方法——计算排序(Counting sorts),在这种算法中没有比较运算,下面简单的介绍一下。
对于这个算法,有个比较重要的约束条件——排列的数据必须在特定的范围,我们假设区间范围为[1, k]。
用到3个数组,A[ ]表示需整理的原数组,B[ ]表示输出的数组结果,C[i ](1<= i <= k)表示在A中每个元素出现的频率,比如C[1]=2表示数组中元素1出现2次。
伪代码如下:
for i= 1 to k
do C[i] = 0; //将数组C 各个值初始化为0
for j = 1 to n
do C[a[j]] = C[a[j]] + 1; // 计算每个元素出现的频率
for i = 2 to k
do C[I] = C[I] + C[I-1]; // 此时的C[i] 表示元素小于等于i的频率,前缀加法
for j = n to 1
do B[C[A[j]] = A[j]
C[A[j]] = C[A[j]] - 1; //最后为分配,较难理解,结合实例自己画画有助于理解
该方法时间复杂度为O(k+n),所以使用时结合k与n的大小,由于排序算法最优为O(nlgn),So
if k <nlgn use Counting sorts
else use Merge sort,由此可见该方法一般处理数据规模较小的序列。
方法二 基数排序算法:可以处理大规模数据,以方法一为基础
主要思想为由低位到高位,按位排序,比如数据{ 237,393, 456},经过
个位排序{ 393, 456, 237 } ——》十位排序{ 237, 456, 393 } ——》 百位排序{ 237, 393, 456}从而得到最终结果。