- 希尔排序平均时间复杂度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 )