資料結構 堆排序

2021-09-06 03:11:41 字數 1564 閱讀 1755

(可先回顧「排序演算法」)

選擇排序的基本思想:每一趟從待排序記錄中選出關鍵字最小的記錄,按順序放在已排序的記錄序列最後,直到全部記錄排序好為止。

堆排序是一種樹形選擇排序,在排序過程中,將儲存待排序記錄的順序表看成是一棵完全二叉樹(區別滿二叉樹)的順序儲存結構。利用完全二叉樹中父結點與子結點的內在關係,在當前無序的序列中選擇關鍵字最小(或最大)的記錄。

《條件》

1)堆的定義:

以任意結點為根結點,根結點的關鍵字都大於(或小於)左、右子樹的根結點。

若堆頂記錄的關鍵字最大,則稱堆為大根堆,反之稱小根堆

2)完全二叉樹的定義:

所有序號大於[n/2](n為結點數)的結點都是葉結點。

因此只需要依次將以[n/2]、[n/2-1]、...、[1]的結點作為根結點的子樹調整為堆即可。

《思路》

(以大根堆為例)

1)調整乙個小堆:

設根結點為rcds[s],左、右子樹根結點分別為rcds[2s]、rcds[2s+1]。

先比較左、右子樹根結點的關鍵字,若較大值為右子樹根結點,則右子樹根結點與根結點比較。若根結點的關鍵字更大,則該小堆滿足要求;若左、右子樹根結點中較大的關鍵字更大,則交換兩個結點。

但是,交換結點後,可能會出現(原)根結點的關鍵字小於(原)右子樹根結點的左、右子樹根結點(rcds[2(2s+1)]、rcds[2(2s+1)+1]))的情況,這時候需要繼續進行調整,即需要迴圈或遞迴。

2)利用完全二叉樹的特性,從[n/2]結點開始往前調整小堆;

3)經過上面兩步只能使乙個無序序列剛好構成堆的條件,還未能稱為有序序列。但我們可以利用堆的特性,將每次調整完得到的堆頂記錄(關鍵字最大)放到最後(依次由[l.length]、[l.length-1]、...),這樣就能得到乙個從左往右,關鍵字從小到大的有序序列。

/*------------調整乙個小堆-------------*/

void adjust_small_heap(sqlist &l, int s, int m) /*s為調整根結點,m為序號最大的結點*/

l.rcds[s] = l.rcds[0]; /*經過上面的迴圈後,s表示的位置可能已經改變,需要重新插入(原)根結點的記錄*/

}/*----------利用完全二叉樹的特性------------*/

void usecbt(sqlist &l) /*cbt->completed binary tree,完全二叉樹*/

/*-------------將大根堆有序化--------------*/

void heap_sort(sqlist &l)

}

資料結構 堆排序 堆排序 Heap Sort

堆排序是一種選擇排序,其時間複雜度為o nlogn 堆的定義 n個元素的序列當且僅當滿足下列關係之一時,稱之為堆。情形1 ki k2i 且ki k2i 1 最小化堆或小頂堆 情形2 ki k2i 且ki k2i 1 最大化堆或大頂堆 其中i 1,2,n 2向下取整 若將和此序列對應的一維陣列 即以一...

資料結構 堆排序

include include void maxheapify int a,int length,int i void buildmaxheapify int a,int length void heapsort int a,int length void main void printf heap...

資料結構 堆排序

1 堆排序的時間複雜度與歸併排序相同,o nlogn 堆排序的優勢在與他只需要固定數量的額外空間,堆排序要比空間複雜性為o n 的歸併排序稍微慢一些,但是比空間複雜性為o 1 的歸併排序要快。2 對序列 26,5,77,1,61,11,59,15,48,19 進行堆排序 過程 調整最大堆 二叉堆 v...