堆是一類特殊的資料結構統稱,堆通常可以被看做一顆樹的陣列物件。
堆滿足下列性質:
1)堆中某個節點的值總是不大於或不小於其父節點的值
2)堆總是一顆完全二叉樹。
完全二叉樹:除最後一層外,每一層上的節點數均達到最大值;在最後一層上只缺少右邊的若干結點。
滿二叉樹:樹中除了葉子節點,每個節點都有兩個子節點
完美二叉樹:滿足完全二叉樹性質,樹的葉子節點均在最後一層(也就是形成了乙個完美的三角形)
堆的定義:n個元素的序列當且僅當滿足以下關係時,稱之為堆。
(ki<=k2i,ki<=k2i+1)或者(ki>=k2i,ki>=k2i+1),(i=1,2,3,..,n/2)
完全二叉樹中所有非終端點的值均不大於(或不小於)其左右孩子節點的值。由此,若序列是堆,則堆頂元素(或完全二叉樹的根)必為序列中n個元素的最小值(或最大值)。
根據上述知道堆的性質,分為大頂堆,和小頂堆。即堆頂元素子串行n個元素中是最大值或最小值。堆排序就是根據這個性質進行排序。
步驟:1. 將輸入的序列初始化為大頂堆
2. 將堆頂元素r[1]與最後乙個元素r[n]交換,此時新的無序區(r1,r2,...,rn-1)和有序區(rn)
3. 將交換後的新的無序區,調整為新的大頂堆。再次將r1與最後乙個元素交換,得到新的無序區(r1,r2,r3,...,rn-2)和有序區(rn-1,rn)
4. 不斷重複2, 3過程,直到有序區個元素個數為n-1,則排序完成。
注意:在第1步初始化大頂堆和第3步中再次調整大頂堆,對序列非葉結點遍歷順序不同。第1步從最後有葉子結點往上調整,第3步中調整最大堆,是從最上面結點開始往下調整。
#include using namespace std;
/****
*堆排序
*首先講待排序列初始化為大頂堆(這裡要理解堆的性質,堆頂元素是最大值)
*將堆頂元素r[1]與最後乙個元素r[n]交換,此時新的無序區(r1,r2,...,rn-1)和有序區(rn)
*將交換後的新的無序區,調整為新的大頂堆。再次將r1與最後乙個元素交換,得到新的無序區(r1,r2,r3,...,rn-2)和有序區(rn-1,rn)
*不斷重複此過程,直到有序區個元素個數為n-1,則排序完成
****/
void sift_down(int *a, int start, int last)
if(left+1 <= last && a[left+1] > a[left])
if(a[left] > a[start])else
cout<< ">>";
for(int i=0;i<=last;i++)
for(int i=n/2 - 1;i>=0;i--)
for(int i=0;i<=n-1;i++)
cout
}
建堆 堆排序
我們前面已經了解過什麼是堆,現在我們來根據它的特徵來研究如何建乙個堆。初始化,申請空間,給堆賦值 建立堆的結構體 typedef struct heap heap 初始化堆 void initheap heap hp,datatype array,int size hp capacity size ...
堆 堆排序學習總結
1.堆是什麼?堆是一種特殊的完全二叉樹.其中,堆又分為最大堆和最小堆.最大堆 任一父節點的值都比左右節點的值大.最小堆 任一父節點的值都比左右節點的值小.2.堆排序的過程 a.最小堆公升序排序 最大堆降序排序類似 建立最小堆 儲存根節點的值 或輸出 把最後乙個節點的值儲存到根節點 堆長減 1 調整為...
二叉堆 堆排序
堆排序與快速排序,歸併排序一樣都是時間複雜度為o n logn 的幾種常見排序方法。學習堆排序前,先講解下什麼是資料結構中的二叉堆。二叉堆是完全二叉樹或者是近似完全二叉樹。二叉堆滿足二個特性 1 父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值。2 每個結點的左子樹和右子樹都是乙個二叉堆...