1. 程式人生 > >堆排序演算法實現

堆排序演算法實現

堆的定義:
在這裡插入圖片描述

堆排序:基本思路,將待排序的一維陣列看成是一個完全二叉樹,將其生成一個堆,由定義可知,根元素必定是最小值(或最大值),將根輸出,然後將剩餘元素再調整成堆。
在這裡插入圖片描述
生成堆的方法:將序列看成一棵完全二叉樹,從最後一個非終端結點[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));
        } 
    }