堆是具有下列性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆。在堆排序中使用到大頂堆。
完全二叉樹的性質:
●如果按照層序遍歷的方式給結點從0開始編號,則結點之間滿足如下關係:
●如果i = 0;則結點i是二叉樹的根,無雙親
●如果i > 0; 對於左孩子,則其雙親是結點i/2;對於右孩子,則其雙親是結點(i/2)-1;那麼對於有n個結點的二叉樹而言,非葉子結點的i值(也就是由左右孩子的結點)小於等於i/2。
堆排序的過程:
<1>構建大頂堆(自下而上調整):從非結點開始,比較左右孩子的大小,獲得值比較大的孩子結點和父結點做比較,如果父結點大於此孩子結點,則進入下一次迴圈,否則交換父結點和孩子結點的值。
<2>得到序列的最大值:將大頂堆的根節點(最大值)與堆中的最後乙個結點進行交換,下一次迴圈中,丟棄最後乙個結點(i--),也就得到序列的最大值。
<3>再次調整成為大頂堆。
完整**:
#include void swap(int arr,int a,int b)
void heapsort(int arr,int i,int len)
if(arr[i] >= arr[j])
swap(arr,i,j);
i = j; }}
void heap(int arr,int len)
for(int i = len -1;i >=0;i--)//i--,每次丟棄最後乙個最大值元素,也就是每次迴圈得到乙個最大值 }
void show(int arr,int len)
}int main()
; int len = sizeof(arr)/sizeof(arr[0]);
heap(arr,len);
show(arr,len);
}
三、堆排序的時間複雜度在構建堆的過程中,因為我們是完全二叉樹從最下層最右邊的非終端結點開始構建,將它與其孩子進行比較和若有必要的互換,對於每個非終端結點來說,其實最多進行兩次比較和互換操作,因此整個構建堆的時間複雜度為o(n);
在正式排序時,第i次取堆頂記錄重建堆需要用o(logi)的時間(完全二叉樹的某個結點到根節點的距離為log2i + 1),並且需要取n - 1次堆頂記錄,因此,重建堆的時間複雜度為o(nlogn)
所以總體來說,堆排序的時間複雜度為o(nlogn).
資料結構 堆排序 堆排序 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...