MIT算法导论5——线性时间排序

来源:互联网 发布:js多个单选框 编辑:程序博客网 时间:2024/05/16 11:02

        常见的排序算法,像归并排序,堆排序时间复杂度为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}从而得到最终结果。