- 堆排序平均效率,最好效率,最坏效率均为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 )