PHP 希尔排序

  • 希尔排序平均时间复杂度O(n^1.3),最好情况O(n),最坏情况O(n^2)
 1 <?php
 2     #希尔排序
 3     function shellSort(Array $arr) {
 4         $k = initStep(count($arr));
 5         $step = pow(2, $k) - 1;
 6         #根据步长进行多次插入排序,依次减少步长,
 7         for(;$step >= 1; $step = pow(2, --$k) - 1) {
 8             $arr = insertSort($arr, $step);
 9         }
10         return $arr;
11     }
12 
13     #求希尔排序初始步长,初始步长公式为2^k<len,len为数组长度,k取最大值
14     function initStep($len) {
15         $k = 0;
16         while(pow(2, $k) < $len) {
17             $k++;
18         }
19         return $k - 1;
20     }
21 
22     #指定部分数组元素按步长向后移动
23     function move(Array $arr, $step, $start = null, $end = null) {
24         if(!isset($start) || $start < 0) $start = 0;
25         if(!isset($end) || $end >= count($arr)) $end = count($arr) - $step - 1;    #最后只能选到倒数第step+1个元素
26         
27         for($i = $end; $i >= $start; $i -= $step) {
28             $arr[$i + $step] = $arr[$i];
29         }
30         return $arr;
31     }
32      
33      #根据步长进行插入排序
34     function insertSort(Array $arr, $step) {
35         #进行step次插入排序
36         for($i = 0; $i < $step; $i++) {
37             #计算本组需要排到的最后一个元素
38             $lastInx = $i;
39             while($lastInx + $step < count($arr)) $lastInx += $step;
40             
41             #进行第i组排序
42             for($j = $i + $step; $j <= $lastInx; $j += $step){#待排序元素从该组第二个元素开始
43                 $insertEle = $arr[$j];    
44                 for($k = $i; $k < $j; $k += $step) {
45                     if($arr[$k] > $arr[$j]) {
46                         $arr = move($arr, $step, $k, $j - $step);
47                         $arr[$k] = $insertEle;
48                         
49                         break;
50                     }
51                 }
52             }
53         }
54         return $arr;
55     }
56     
57     $arr = array(5, 1, 7, 4, 6, 2, 9, 11, 54, 0);
58     $arr = shellSort($arr);
59     print_r($arr);
60 ?>

输出

Array ( [0] => 0 [1] => 1 [2] => 2 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 9 [8] => 11 [9] => 54 )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值