堆排序分析及php實現

2021-09-08 11:41:05 字數 1582 閱讀 2576

堆排序:是一種特殊形式的選擇排序,他是簡單選擇排序的一種改進。

什麼是堆?

具有n個元素的序列: 

(ki <= k2i,ki <= k2i+1) 或者 (ki >= k2i,ki >= k2i+1), (i = 1,2,3,4...n/2)

滿足這個條件時,該序列就是乙個堆。第乙個條件稱為小頂堆,第二個條件稱為大頂堆。

為了方便,下邊論述基於大頂堆,並且下標從1開始。

將堆的元素放在一棵完全二叉樹中,方便我們討論堆的特性和排序,一般談到堆也都是一棵完全二叉樹。

完全二叉樹:若二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹。

堆的特性(括號道標下標從0開始的計算方法) :

堆排序:

核心思想:

將原始序列構成乙個堆。(建立初始堆)

交換堆的第乙個元素(最大值)和最後乙個元素的位置,把堆長度減一後剩餘的序列再轉換為乙個堆。(調整堆)

重複2過程n-1次。

經過上述操作,就可以將乙個無序序列從小到大排序。(因為大頂堆每次把最大值交換到最後了,所以想要降序排列就要用小頂堆)

先說調堆,調堆就是把當前節點和其左子樹,右子樹中最大值交換,依次把需要調整的節點調一遍。這樣一次迴圈下來根節點肯定放的是最大值。但是有可能迴圈中的某次交換把之前排好序的結構打亂,需要遞迴調整。

再說建堆,建堆就是從最後乙個非葉子節點開始,到第乙個節點為止,依次進行調堆。

for ($i = floor(count($arr) / 2) - 1; $i >=0; $i--) 

借用網上的一張圖說明一下:

從floor(9/2)-1開始,也就是key=3,val=5的地方開始,迴圈調堆,到圖1.6處迴圈完成,最大值順利到達根節點,但是發現val=1節點還是需要調整,這就需要在調堆裡執行迴圈調整,使其符合堆的特性。

**實現:

$arr = [49, 38, 65, 97, 76, 13, 27, 50];

sortheap(

$arr

);print_r($arr

);function sortheap(&$arr)}

function buildheap(&$arr)}

//調整堆,接受maxlen為當前堆需要調整的元素最大值,node為當前要調整的節點

function adjustheap(&$arr, $maxlen, $node

)

if ($rchild

< $maxlen && $arr[$rchild] > $arr[$max

])

if ($max != $node

) else

}}function swap(&$arr, $m, $n

)

堆排序分析及php實現

堆排序 是一種特殊形式的選擇排序,他是簡單選擇排序的一種改進。什麼是堆?具有n個元素的序列 ki k2i,ki k2i 1 或者 ki k2i,ki k2i 1 i 1,2,3,4.n 2 滿足這個條件時,該序列就是乙個堆。第乙個條件稱為小頂堆,第二個條件稱為大頂堆。為了方便,下邊論述基於大頂堆,並...

排序演算法 堆排序演算法實現及分析

堆排序 heap sort 就來利用堆 假設利用大頂堆 進行排序的方法。它的基本思想是,將待排序的序列構成乙個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它移走 其實就是將其與堆陣列的末尾元素交換,此時末尾元素就是最大值 然後將剩餘的n 1個序列重新構造成乙個堆,這樣就會得到n個元素中的次小值...

堆排序分析實現

演算法思想 若公升序,建大堆,每次選擇堆頂元素即最大的數,和最後一位交換,再縮小堆的範圍 避免剛排好的最後乙個位置被調回去 對剩下的進行向下調整 此時只有根節點不對,左右子樹都滿足大堆 反覆進行直到堆的範圍為0.則資料就有序了。實現思路 堆排序的實現首先是需要將陣列調整為乙個大堆或者小堆,然後就是迴...