十大基礎實用演算法補全 堆排序(HeapSort)

2021-07-30 15:31:19 字數 1368 閱讀 3361

2023年的計算機先驅獎獲得者、史丹福大學電腦科學系教授羅伯特·弗洛伊德(robert w.floyd)和威廉士(j.williams)在2023年共同發明了著名的堆排序演算法(heap sort )

在了解堆排序演算法的原理之前,我們必須先來了解一下什麼是堆?堆就是乙個近似的完全的二叉樹。那什麼又是完全二叉樹呢?完全二叉樹的定義如下:

若設二叉樹的高度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層從右向左連續缺若干結點,這就是完全二叉樹。

完全二叉樹圖示:

由上面這幅圖可看出完全二叉樹的特點:最後一層從左向右連續缺失節點。

堆就是將陣列表示為完全二叉樹的形式,那麼如何把陣列轉換成堆呢?接下來以乙個圖演示陣列轉換成堆。假設有乙個整型陣列:{5,4,8,3,2,1}

了解完堆的概念之後,我們還需要知道大根堆:大根堆中就是每個父節點的資料大於子節點中的資料。小根堆則相反,每個父節點的資料小於子節點。下面就是乙個大根堆跟乙個小根堆

堆排序的原理就是每次將未排序陣列構建成乙個大根堆或者是乙個小根堆,得到根節點便是未排序陣列中的最大或者是最小值,然後將根節點即陣列中第乙個資料跟未排序陣列中的最後乙個元素即進行交換。然後將未排序陣列的數量減一,再次構建大根堆或者小根堆。以此類推,直到未排序陣列剩下乙個元素。下面以大根堆為例:

按照上圖的做法不斷迴圈直到最後未排序陣列中剩下乙個元素,排序完成。

#include 

/** 前提:元素i之後的元素構成大根堆

目的:令元素i包括進來以後仍為大根堆

array:待調整堆陣列

i:待調整陣列元素位置

nlength:陣列長度

*/void heapadjust(int

array, int i, int nlength)

//比較較大子結點和父結點大小,子結點較大就上移

if (array[i] < array[nchild])

else

}}//堆排序

void heapsort(int

array, int length)

//從最後乙個元素開始,將最大的元素和最後乙個元素交換,並調整。

//迴圈操作

for (i = length - 1; i > 0; --i)

}int main()

; heapsort(num, sizeof(num)/sizeof(int));

for (i = 0; i < sizeof(num)/sizeof(int); i++)

printf("\nok\n");

return

0;}

執行結果:

關於堆排序複雜度計算,大家可以參考:堆排序演算法複雜度解析

十大排序演算法之堆排序

堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法,它是一種選擇排序,時間複雜度是o n log n 本部落格將使用最大堆來實現堆排序。對於堆的具體描述在本部落格的這篇文章 已經對最大堆這種資料結構做出了介紹,故不做重複介紹,主要介紹堆排序。以下是最大堆結構具體實現過程 impo...

十大排序 堆排序

堆排序屬於選擇排序 選擇排序的基本思想 每一趟 第i趟 在後面n i 1個待排序的元素中選取關鍵字最小的元素,作為有序子串行的第i個元素,直到第 n 1趟做完,待排序元素只剩下1個,就不用再選了。堆排序適合關鍵字較多的情況 n 1000 比如 在1億個數中選出前100個最大值?首先使用乙個大小為10...

演算法 十大排序 堆排序 大頂堆

堆排序 大頂堆 大頂堆和小頂堆的差別在與大頂堆的根節點比它的子節點和葉子節點都要大,大頂堆輸出的時候是正序的而小頂堆是逆序的 同樣的也是有兩步 1,堆化 2,下調public class 03 堆排序大頂堆 sort a for int i 0 i a.length i 進行堆化 public st...