排序演算法 堆排

2021-10-07 01:45:42 字數 1176 閱讀 7889

堆排序

如果將堆結構中的資料看作是一顆完全二叉樹的各個節點,那麼堆的性質就是滿足如下性質的完全二叉樹:樹中任意非葉子節點的關鍵碼均不大於或不小於其左右孩子節點的關鍵碼。利用堆的有序性及其運算,可以容易的實現選擇排序的方法稱為堆排序。

假設欲對含有n個物件的序列v[0]、v[1]、v[n-1]進行堆排序,演算法主要分為兩個步驟:一是根據初始輸入資料利用堆的調整演算法形成初始堆,二是通過一系列的物件交換和重新調整對堆進行排序。具體的過程是在首次獲得最大堆之後,將關鍵字最大的元素v[0](即堆頂)和無序區的最後乙個元素v[n-1]進行交換。由此得到新的無序區v[0]、v[1]、v[n-2]和有序區v[n-1],且滿足v[0…n-2]中元素的關鍵碼不大於v[n-1]的關鍵碼。由於交換後新的堆頂v[0]可能違法堆的性質,因此再利用堆的調整演算法對無序區v[0…n-2]進行調整。調整完成後將關鍵碼最大的元素v[0]和無序區的最後乙個元素v[n-2]交換,並再次利用堆的調整演算法對無序區進行調整,這個過程直到無序區中僅剩乙個元素為止。

/*堆排是從底向上的調整方式

最後乙個父親節點的位置是 n / 2 - 1(陣列是從0開始的)

假設陣列中有10個元素

將最大的元素放在陣列的最後

這時候樹中需要排序的數量減1,剩下9個元素

在這9個元素中,只有剛才頂部交換的元素不符合大頂堆,其他元素都符合大頂堆

再對現在的頂部元素的位置呼叫剛才的函式介面adjust_max_heap

該函式介面執行一次只調整乙個節點。

調整後,再將該元素和陣列中的倒數第二個元素進行交換,陣列的len會不斷變小

堆排的所有時間複雜度都是nlog2n*/

void

adjust_max_heap

(int

* arr,

int adjustpos,

int arrlen)

if(arr[dad]

< arr[son]

)else}}

void

arr_heap

(int

* arr)

swap

(arr[0]

, arr[n -1]

);//交換頂部與最後乙個元素

for(i = n -

1; i >

1; i--

)}

排序總結 堆排

核心函式 adjustdown nums,i,n 將 i 節點下沉。void adjustdown int arr,int i,int n else break 通過自底向上對每個節點呼叫下沉函式adjustdown,就能實現建立最大堆 最小堆。因為葉節點不存在子節點,所以實際上i從 n 2 1開始...

2011 4 15 快排演算法,堆排演算法

template int get pivot index value type array,int start,int end value type pivot array start while start end while startpivot end array start array en...

33 排序演算法(6) 堆排序

之前所講的演算法,很多都是 o n2 的,造成這些演算法複雜度較高的主要原因是它們一次又一次地重複地進行這比較操作,並沒有利用之前的比較得到的結果。希爾排序對直接插入排序進行改進,使得這種方法的複雜度從 o n2 下降到 o nlog n 在這裡我們將接著介紹一種利用之前排序結果的方法,堆排序。若設...