學習PHP中堆排序算法的原理及時間復(fù)雜度分析
堆排序是一種基于堆數(shù)據(jù)結(jié)構(gòu)的排序算法,它的時間復(fù)雜度為O(nlogn)。本文將介紹PHP語言中堆排序算法的原理,同時提供代碼示例。
一、堆的定義和性質(zhì)
在學習堆排序之前,首先需要了解堆的定義和性質(zhì)。堆是一種完全二叉樹,其每一個節(jié)點的值都大于或等于其子節(jié)點的值,我們把這樣的堆稱之為大頂堆。相反,如果每一個節(jié)點的值都小于或等于其子節(jié)點的值,我們稱之為小頂堆。
由于堆的特性,堆頂元素即為最大或最小值,因此在堆排序中,我們通常將待排序的數(shù)組看作一個完全二叉樹,并利用堆的特性進行排序。
二、堆排序算法的原理
堆排序算法主要分為構(gòu)建堆和調(diào)整堆兩個步驟。
- 構(gòu)建堆(buildHeap):將待排序的數(shù)組調(diào)整為一個大頂堆。
步驟如下:
從最后一個非葉子節(jié)點(即n/2-1)開始逐個向前遍歷,調(diào)用調(diào)整堆的函數(shù)(adjustHeap)。調(diào)整堆的函數(shù)采用自上而下的方式,對當前節(jié)點及其子樹進行調(diào)整,保證當前節(jié)點大于其子節(jié)點。重復(fù)以上兩個步驟,直到整個數(shù)組調(diào)整為一個大頂堆。
- 調(diào)整堆(adjustHeap):將當前節(jié)點及其子樹調(diào)整為一個大頂堆。
步驟如下:
根據(jù)當前節(jié)點的位置計算其左右子節(jié)點的位置。比較當前節(jié)點和其左右子節(jié)點的值,找到最大節(jié)點的位置。如果最大節(jié)點的位置不是當前節(jié)點的位置,則交換最大節(jié)點和當前節(jié)點的值,并遞歸調(diào)用自身對交換后的子樹進行調(diào)整。
- 排序(sortHeap):將堆頂元素(即數(shù)組的第一個元素)與最后一個葉子節(jié)點交換,然后對剩余的n-1個元素進行堆調(diào)整。
步驟如下:
將堆頂元素與最后一個葉子節(jié)點交換。縮小堆的范圍,即忽略已經(jīng)排序好的最后一個葉子節(jié)點。對縮小范圍的堆進行調(diào)整,保持大頂堆的性質(zhì)。重復(fù)以上三個步驟,直到堆的范圍縮小為1。
三、PHP代碼示例
下面是PHP語言實現(xiàn)堆排序算法的示例代碼:
function heapSort(&$arr) { $length = count($arr); // 構(gòu)建大頂堆 for ($i = floor($length/2 - 1); $i >= 0; $i--) { adjustHeap($arr, $i, $length); } // 調(diào)整堆并排序 for ($i = $length - 1; $i >= 0; $i--) { // 交換堆頂元素和最后一個葉子節(jié)點 $temp = $arr[0]; $arr[0] = $arr[$i]; $arr[$i] = $temp; // 調(diào)整堆使其保持大頂堆性質(zhì) adjustHeap($arr, 0, $i); } } function adjustHeap(&$arr, $i, $length) { $largest = $i; // 最大值的位置 $left = $i * 2 + 1; // 左子節(jié)點的位置 $right = $i * 2 + 2; // 右子節(jié)點的位置 // 比較當前節(jié)點與左右子節(jié)點的值,找到最大值的位置 if ($left < $length && $arr[$left] > $arr[$largest]) { $largest = $left; } if ($right < $length && $arr[$right] > $arr[$largest]) { $largest = $right; } // 如果最大值的位置不是當前節(jié)點的位置,則交換兩個位置的值,并遞歸調(diào)整堆 if ($largest != $i) { $temp = $arr[$i]; $arr[$i] = $arr[$largest]; $arr[$largest] = $temp; adjustHeap($arr, $largest, $length); } } // 測試 $arr = [8, 3, 6, 2, 9, 1]; heapSort($arr); print_r($arr); // 輸出 [1, 2, 3, 6, 8, 9]
登錄后復(fù)制
四、時間復(fù)雜度分析
堆排序的時間復(fù)雜度為O(nlogn)。其中,構(gòu)建堆的時間復(fù)雜度為O(n),調(diào)整堆的時間復(fù)雜度為O(logn)。由于要對n個元素進行排序,因此總的時間復(fù)雜度為O(nlogn)。
總結(jié)
本文詳細介紹了PHP語言中堆排序算法的原理,同時提供了相應(yīng)的代碼示例。堆排序是一種高效的排序算法,適用于待排序的數(shù)組較大的情況。通過學習堆排序算法,可以進一步提升對數(shù)據(jù)結(jié)構(gòu)和算法的理解和應(yīng)用能力。
以上就是學習PHP中堆排序算法的原理及時間復(fù)雜度分析。的詳細內(nèi)容,更多請關(guān)注www.92cms.cn其它相關(guān)文章!