排序方法的时间复杂度 稳定排序算法有哪些( 二 )


但是在一般情况下,K并不能再被认为是个常数 。那K应该是什么呢 。这里我们以十进制的数为例 。整数序列中的每个数是以10为底的数 。不妨我们用b记为底数,即b=10 。那如果整个整数序列中的最大数是N 。那这就很容易看出,K= logbN 。所以在一般情况下,基数排序的时间复杂度可以看做是O(n logbN) 。在N非常大的情况下是不是基数排序的效率要低于比最优的比较型的排序算法(最优的比较型的排序算法的时间复杂度是O(nlogn)) 。现在让我们假设N <= nc,这里c是一个常数 。这种情况下基数排序的时间复杂度就变成了O(n logbn) 。但是即使这样,也不能比复杂度是O(nlogn)的比较型排序算法更快 。那如果我们使b的值变大呢?如果我们使得b的值为n的话,这样基数排序的时间复杂度是不是就变成了线性的了,即O(n) 。也就是说,如果待排序的序列的数是以n为底的话,那序列中的数可以是1到nc 之间的数 。其时间复杂度就是线性的 。
好了,对于基数排序的效率问题,我们就先讨论到这里 。接下来就该进入我们的核心问题——LSD基数排序代码的实现 。
function FindMaxBit($arr){$p = $arr[0];for($i=1;$i=$p){$p = $arr[$i];}}//得到最大的数以后,计算出该数据有多少位$d = 1;while(floor($p/10)>0){$d;$p = floor($p/10);}return $d;}function LSD_RadixSort(&$arr){//得到序列中最大位数$d = FindMaxBit($arr);$bucket = array();//初始化队列for($i=0;$i<10;$i){$bucket[$i]=array(\\\'num\\\'=>0,\\\'val\\\'=>array());}$radix = 1;for($i=1;$i<=$d;$i){for($j=0;$j $val) {for ($j = 0; $j < $val[\\\'num\\\']; $j) {$arr[] = $val[\\\'val\\\'][$j];}}for($l=0;$l<10;$l){$bucket[$l]=array(\\\'num\\\'=>0,\\\'val\\\'=>array());}$radix *= 10;}}$arr = array(15,77,23,43,90,87,68,32,11,22,33,99,88,66,44,113,224,765,980,159,456,7,998,451,96,0,673,82,91,100);LSD_RadixSort($arr,0,count($arr)-1);print_r($arr); 在上面的代码中,我是将实际的数据直接存放在桶中了 。然后将桶中的数据按照顺序覆盖掉原队列中的数据 。然后再次将被覆盖后的队列进行分组,依次进行下去 。
当然还有一种方式就是,申请一个和原序列相同大小的队列(不妨成为临时队列),然后再申请一个用于作桶的数组 。桶中只是存放原序列中的数在临时队列中的位置,然后将原序列中的数按照桶中的顺序放入临时队列中 。然后将临时队列整个赋值给原序列 。
二者虽然实现方式不同,但是其空间复杂度是相同的 。下面我们看后者应该如何用代码实现 。
function LSD_RadixSort(&$arr){//得到序列中最大位数$d = FindMaxBit($arr);$bucket = array();$temp = array();//初始化队列for($i=0;$i

推荐阅读