堆排序演算法實現
阿新 • • 發佈:2018-11-27
堆的定義:
堆排序:基本思路,將待排序的一維陣列看成是一個完全二叉樹,將其生成一個堆,由定義可知,根元素必定是最小值(或最大值),將根輸出,然後將剩餘元素再調整成堆。
生成堆的方法:將序列看成一棵完全二叉樹,從最後一個非終端結點[n/2]開始,將該點與它的左右子樹根結點比較,將最小的移動到該結點位置,一直將該結點移動到使該子樹符合堆定義為止,一直遍歷到序列第1個結點,就構造好了一個堆。
調整堆的方法:如下圖,如果將13輸出,然後將序列中最後一個值97移到第一位,可知,破壞了堆的結構,需要調整,判斷左右子樹根節點,取值小的27與97互換,可知右子樹對結構被破壞,用同樣的方法進行調整,
程式碼實現:
/** * @name 陣列排序堆排序 * @use 使用堆排序演算法將陣列進行排序,陣列型別為每個元素都含有“value”屬性用於排序 * @param arr 陣列 * @param height 待排序段的最高下標 */ public static function sortStack(&$arr) { $arr[] = $arr[0]; unset($arr[0]); self::createStack($arr); $num = count($arr); for ($i = $num; $i > 1; $i--) { $temp = $arr[$i]; $arr[$i] = $arr[1]; $arr[1] = $temp; self::adjustStack($arr, 1, $i - 1); } } public static function adjustStack(&$arr, $index, $height) { $leftChild = 2 * $index; $rightChild = 2 * $index + 1; $temp = $arr[$index]; if ($leftChild > $height) { return ; } if ($rightChild > $height) { if ($arr[$leftChild]['value'] < $arr[$index]['value']) { $arr[$index] = $arr[$leftChild]; $arr[$leftChild] = $temp; } return ; } if ($arr[$leftChild]['value'] <= $arr[$rightChild]['value'] && $arr[$leftChild]['value'] < $arr[$index]['value']) { $arr[$index] = $arr[$leftChild]; $arr[$leftChild] = $temp; self::adjustStack($arr, $leftChild, $height); } else if ($arr[$leftChild]['value'] > $arr[$rightChild]['value'] && $arr[$rightChild]['value'] < $arr[$index]['value']) { $arr[$index] = $arr[$rightChild]; $arr[$rightChild] = $temp; self::adjustStack($arr, $rightChild, $height); } } public static function createStack(&$arr) { for ($i = floor(count($arr) / 2); $i > 0; $i--) { self::adjustStack($arr, $i, count($arr)); } }