排序演算法之堆排序

2021-06-21 13:05:42 字數 2358 閱讀 6541

堆排序演算法是選擇排序的一種,該演算法只是通過堆,最大堆、或者最小堆選擇出乙個待排序序列中的最大值,或者最小值。要想實現堆排序演算法,就需要構建什麼堆,這裡也最小堆為例。說明什麼是堆,怎麼構建乙個堆。

假設待排序序列為a[n] 為乙個陣列。陣列的長度為n 陣列下標為 0,1,2,…i,….2i,2i+1….n-1;

堆是乙個有序的二叉樹。乙個二叉樹滿足如下條件就是乙個堆。下面以最小堆為例:

l 樹中的非葉節點的資料小於或者等於左右孩子節點的資料。

在隊中,沒有規定節點的左右孩子的大小,只規定了父節點和子節點資料之間必須滿足的條件。當從小到大的順序輸出資料時,要求根節點是最大值。

堆排序有連個階段:

1.         將無序的資料a[n]構成堆,(即用無序的資料生成滿足堆定義的完全二叉樹)。

2.         利用堆排序(利用上一步生成的堆輸出有序的資料)。

下面說明如何構成堆:

獲取最後乙個非葉節點,和左右孩子節點比較將最大值移動到父節點。比如:n/2 就是最後乙個非葉節點。假如此時乙個非葉節點的序號為 k 則 k >0 並且 k< n

上乙個非葉節點 k -1 , 和 2(k-1) 左節點 、2k右節點中較大的進行比較,如果大於跟節點就和跟節點進行交換,否則不交換。如果交換,加入k -1 和 2(k)交換的,則需要將2k作為父節點進行比較檢測,因為k-1 和 2k進行了交換說明k-1小於 2k 而 2k 處的值是以2k為父節點的子樹的最大值,一旦交換,則不能保證還是最大值。

如a[n] = 將其放在二叉樹中,如下圖所示:

圖中,黃色背景表示:進行比較的根節點。將該節點和左右子樹比較,是否交換要看交換結果。第一次交換結果、第二次交換如下圖:

本次交換,90 比6,28都大,本次比較不需要交換。

下一次比較和交換:如下圖:

下一次:

本次交換完成,但是因為將較小的數放在了節點2 處,一次要遍歷 以 2 為根節點的所有子樹,以保證,2 節點也是乙個符合 左右孩子節點的值都比父節點的值小。 因此將 2 號所在未知的節點重新遍歷。如下:

最後結果:

這個整個二叉樹就成為乙個最大堆。

以上描述的是堆的形成過程。堆排序就是基於這樣的過程的。

待排序序列構成乙個最大堆,然後將最大的數放在待排序序列的最後,將出去最後序列的剩餘資料生成最大堆,一次迴圈,就可以將待排序的資料變成有序序列。

有以上可知,堆排序的過程中生成最大堆是堆排序的難點。在生成最大堆以後,很容易進行堆排序了,以下是堆排序中生成堆的流程圖:

將如當前排序的序列是a[n], 最大非葉節點是 s 序列的長度為n

對排序的整體實現:c++

#include

using namespace std;

void gengrateheap(int array,int s,int n);

void heapsort(int array,int n);

void output(int array,int n);

int main()

;output(a,8);

heapsort(a,8);

output(a,8);

system("pause");

return 0;

}//輸出整個排序序列

void output(int array,int n)

cout

//將s為根節點生成乙個堆

void gengrateheap(int array,int s,int n)

}if(array[s]

else}}

//堆排序的實現

void heapsort(int array,int n)

for(int j =n-1;j>0;j--)

}本程式在vc++6.0中能夠正確執行。

排序演算法之堆排序

前言 今天我來介紹下堆排序,在寫堆排序 之前,我們要知道堆的概念!堆的定義 n個關鍵字序列kl,k2,kn稱為 heap 當且僅當該序列滿足如下性質 簡稱為堆性質 1 ki k 2i 且ki k 2i 1 1 i n 當然,這是小根堆,大根堆則換成 號。k i 相當於二叉樹的非葉子結點,k 2i 則...

排序演算法之堆排序

宣告 本博文 為樓主親自編寫並測試,其它內容引用至我一直很崇拜的牛人morewindows。他對排序演算法的講解通俗易懂,給人一種耳目一新的感覺。堆排序與快速排序 歸併排序 一樣都是時間複雜度為o n logn 的幾種常見排序方法。最小堆的講解以及最小堆元素的插入和刪除參見最小堆操作。以下繼續引用以...

排序演算法之堆排序

堆排序是一種樹形選擇排序,是對直接選擇排序的有效改進。堆是一種資料結構,其定義 任何乙個非葉結點的值,都不大於 或不小於 其左右孩子結點的值。若父親大孩子小,則這樣的堆叫做大頂堆 若父親小孩子大,則這樣的堆叫做小頂堆。顧名思義,大頂堆的根結點的值是最大的,小頂堆的根結點的值是最小的。首先,將乙個無序...