堆可以被近似看成乙個近似完全二叉樹
以結點數為10的樹為例
給定乙個節點下標為i,則其父,子節點分別為
parent(i)
return i/2 //父結點
left(i)
return 2*i //左子結點
right(i)
return 2*i+1 //右子結點
如 i= 2則其左子結點為4 右子節點為5 父節點為1
二叉堆可分為兩種形式
最大堆所有結點父結點要大於等於其自身
最小堆所有結點父結點都要小於其自身
維護堆的性質
在輸入新的資料時可能會導致堆違背最大堆性質通過呼叫乙個函式,使以新的樹位
根節點的子樹重新遵循最大堆的性質。
原書偽**
maxheap(a,i)
l = left(i) //找出左右子結點的編號
r = right(i)
if l <= a.heap-size and a[l] > a[i] //判斷i與其左右子結點大小關係,並確定最大結點的編號
largest = l;
else largest = i
if r <= a.heap-size and a[r] > a[largest]
largest = r
if largest != i //如果最大結點不是i則交換i與其子結點的值,使其滿足最大子樹堆
exchange a[i] with a[largest]
maxheap(a,largest) //調換之後其子節點也可能不滿足最大堆性質,所以要逐層遞迴呼叫
建堆在擁有維護堆性質工具後,我們可以進行最大堆的建立。
我們要對除葉子結點(即度為0的結點,無子樹)的其他結點呼叫maxheap以維護
最大堆的性質。
n/2+1 to n 中的元素都是葉子結點
所以對1 to n/2所有結點呼叫維護函式
原書偽**
buildmaxheap
a.heap-size = a.length //實際元素數量 陣列元素數量
for i = a.length/2 down to 1
maxheap(a,i)
利用最大堆我們可以進行排序,根據最大堆的性質,根結點總是最大的結點,所以
只要一次比較根節點,即可進行排序,並在過程中不斷維護最大堆性質,以滿足根節點最大,
注意排過序的結點不應再被維護,所以應該將實際元素個數縮小
原書偽**
heapsort(a)
buildmaxheap(a)
for i = a.length down to 2
exchange a[1] with a[i]
a.heap-size = a.heap-size-1
maxheap(a,1)
c語言實現堆排序
#includeint truesize = 10; //實際堆中的元素(此程式堆中元素為10個等於陣列元素數量
int parent(int i) //計算關係結點編號
int left(int i)
int right(int i)
void maxheap(int a,int i) //維護最大堆性質
}void buildmaxheap(int a) //建立最大堆
}void heapsort(int a) //堆排序
}int main()
執行樣例 演算法導論 6 堆排序
堆的分類 最大堆性質 高度 對於堆的一些基本操作 偽 描述 實現 max heapify python實現 123 4567 891011 1213 def max heapify i print max heapify i l left i r right i if l heap size and...
演算法導論之五堆排序
堆排序的時間複雜度是,與插入排序相似,堆也具有空間原址性,即任何時候都只需要常數個額外的元素空間儲存臨時資料。1.堆簡介 1 堆是乙個陣列,表示堆的陣列a包括兩個屬性 a.length表示陣列元素的個數,a.heap size表示有多少個堆元素儲存在該陣列中。給定一結點的下標i,可以得到其父結點 左...
演算法導論複習(3) 堆排序
堆排序與歸併排序具有相同的時間複雜度o nlgn 但是在講堆排序之前,先要搞清楚堆排序使用的 二叉堆 二叉堆是乙個陣列,可以被看成近似的完全二叉樹 特點 1.樹上每一節點對應乙個元素,除最底層外,樹是完全充滿的,而且從左到右填充。2.a 大頂堆 根節點的值是大於等於任何子節點的值 b 小頂堆 根節點...