PHP堆排序實現代碼

來源:互聯網
上載者:User
堆可以視為一棵完全的二叉樹,除了最底層之外,每一層都是滿的,這使得堆可以利用數組來表示,每一個結點對應數組中的一個元素。
數組與堆之間的關係:
二元堆積一般分為兩種:最大堆和最小堆。
最大堆:堆中每個父節點的元素值都大於等於其孩子結點(如果存在);

最小堆:堆中每個父節點的元素值都小於等於其孩子結點(如果存在);

什麼是堆排序

堆排序(假設利用最大堆)就是把堆頂的最大數取出,將剩餘的堆繼續調整為最大堆

堆排序演算法

建堆:建堆是不斷調整堆的過程,從 len/2 處開始調整,一直到第一個節點,此處 len 是堆中元素的個數。建堆的過程是線性過程,從 len/2 到 0 處一直調用調整堆的過程,相當於 o(h1) + o(h2) …+ o(hlen/2) 其中 h 表示節點的深度,len/2 表示節點的個數,這是一個求和的過程,結果是線性 O(n)。

調整堆:調整堆在構建堆的過程中會用到,而且在堆排序過程中也會用到。利用的思想是比較節點i和它的孩子節點 left(i) , right(i),選出三者最大(或者最小)者,如果最大(小)

值不是節點i而是它的一個孩子節點,那邊互動節點i和該節點,然後再調用調整堆過程,這是一個遞迴的過程。調整堆的過程時間複雜度與堆的深度有關係,是 logn 的操作,因

為是沿著深度方向進行調整的。

堆排序:堆排序是利用上面的兩個過程來進行的。首先是根據元素構建堆。然後將堆的根節點取出(一般是與最後一個節點進行交換),將前面 len-1 個節點繼續進行堆調整的過

程,然後再將根節點取出,這樣一直到所有節點都取出。堆排序過程的時間複雜度是 O(nlogn)。因為建堆的時間複雜度是 O(n)(調用一次);調整堆的時間複雜度是 logn,調

用了 n-1 次,所以堆排序的時間複雜度是O(nlogn)。

例子:

<?php// PHP 堆排序演算法實現、堆排序時間複雜度分析/** * 堆排序 * @param array $arr */function heap_sort(array &$arr){    $count = count($arr);    // 建堆 (下標小於或等於floor($count/2)-1的節點都是要調整的節點)    for($i = floor($count / 2) - 1; $i >= 0; $i --)    {        heap_adjust($arr, $i, $count);    }    // 調整堆    for($i = $count - 1; $i >= 0; $i--)    {        //將堆頂元素與最後一個元素交換        swap($arr,0,$i);        heap_adjust($arr,0,$i - 1);    }}/** * 交換2個值 * @param array $arr * @param int $a 數組下標 * @param int $b 數組下標 */function swap(array &$arr, $a, $b){    $temp = $arr[$a];    $arr[$a] = $arr[$b];    $arr[$b] = $temp;}/** * 交換2個值 * @param array $arr * @param int $start 數組下標 * @param int $end 數組下標 */function heap_adjust(array &$arr, $start, $end){    $temp = $arr[$start];    //沿關鍵字較大的孩子節點向下篩選,這裡數組開始下標識0    for($j = 2 * $start + 1; $j <= $end; $j = 2 * $j + 1)    {        if($j != $end && $arr[$j] < $arr[$j + 1])        {            $j ++;        }        if($temp < $arr[$j])        {        //將根節點設定為子節點的較大值        $arr[$start] = $arr[$j];        $start = $j;        }    }    $arr[$start] = $temp;}// 使用$arr = array(8,4,2,9,3,7,1,6,5);heap_sort($arr);print_r($arr);

輸出:

Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 )

時間複雜度分析

總體上來說,堆排序的時間複雜度是 O(nlogn)。由於堆排序對原始記錄的排序狀態並不敏感,因此它無論是最好、最差和平均時間複雜度都是 O(nlogn)。這在效能上顯然要遠遠好於冒泡、簡單選擇、直接插入的 O(n^2) 的時間複雜度了。
堆排序是一種不穩定排序方法(排序前後相同元素的前後順序可能改變)。

相關推薦:

JavaScript中的堆排序詳解

PHP排序演算法之堆排序詳解

PHP堆排序演算法執行個體詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.