- 堆排序平均效率,最好效率,最壞效率均為O(nlogn)
1 <?php 2 #堆排序 3 function heapSort(&$arr) { 4 #初始化大頂堆 5 initHeap($arr, 0, count($arr) - 1); 6 7 #開始交換首尾節點,並每次減少一個末尾節點再調整堆,直到剩下一個元素 8 for($end = count($arr) - 1; $end > 0; $end--) { 9 $temp = $arr[0];10 $arr[0] = $arr[$end];11 $arr[$end] = $temp;12 ajustNodes($arr, 0, $end - 1);13 }14 }15 16 #初始化最大堆,從最後一個非葉子節點開始,最後一個非葉子節點編號為 數組長度/2 向下取整17 function initHeap(&$arr) {18 $len = count($arr);19 for($start = floor($len / 2) - 1; $start >= 0; $start--) {20 ajustNodes($arr, $start, $len - 1);21 }22 }23 24 #調整節點25 #@param $arr 待調整數組26 #@param $start 調整的父節點座標27 #@param $end 待調整數組結束節點座標28 function ajustNodes(&$arr, $start, $end) {29 $maxInx = $start;30 $len = $end + 1; #待調整部分長度31 $leftChildInx = ($start + 1) * 2 - 1; #左孩子座標32 $rightChildInx = ($start + 1) * 2; #右孩子座標33 34 #如果待調整部分有左孩子35 if($leftChildInx + 1 <= $len) {36 #擷取最小節點座標37 if($arr[$maxInx] < $arr[$leftChildInx]) {38 $maxInx = $leftChildInx;39 }40 41 #如果待調整部分有右子節點42 if($rightChildInx + 1 <= $len) {43 if($arr[$maxInx] < $arr[$rightChildInx]) {44 $maxInx = $rightChildInx;45 }46 }47 }48 49 #交換父節點和最大節點50 if($start != $maxInx) {51 $temp = $arr[$start];52 $arr[$start] = $arr[$maxInx];53 $arr[$maxInx] = $temp;54 55 #如果交換後的子節點還有子節點,繼續調整56 if(($maxInx + 1) * 2 <= $len) {57 ajustNodes($arr, $maxInx, $end);58 }59 }60 }61 62 $arr = array(1, 5, 3, 7, 9 ,10, 2, 8);63 heapSort($arr);64 print_r($arr);65 ?>
輸出
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 5 [4] => 7 [5] => 8 [6] => 9 [7] => 10 )