堆排序:是一種特殊形式的選擇排序,他是簡單選擇排序的一種改進。
什麼是堆?
具有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.則資料就有序了。實現思路 堆排序的實現首先是需要將陣列調整為乙個大堆或者小堆,然後就是迴...