堆排序不同於歸併排序的是,堆排序具有和插入排序一樣的空間原址性,任何時候都只需要常數個額外的元素空間儲存臨時資料。因此,堆排序是集合了插入排序和歸併排序兩種演算法優點的排序方法。
(二叉)堆是乙個陣列,它可以被看成乙個近似的完全二叉樹。樹上的每乙個結點對應陣列中的乙個元素,除了最底層,該樹是完全充滿的,而且是從左到右填充。給定下面三個函式(這裡計算左右孩子的方式說明陣列是從1開始編號的,即a[1, a.heap_size],如果是a[0, a.heap_size-1]的話,則左右孩子的索引應該是2*i+1, 2*i+2),在堆排序的好的實現中,這三個函式通常是以「巨集」或者「內聯函式」的方式實現的:
parent(i)
return i/2
left(i)
return 2*i
right(i)
return 2*i+1
二叉堆有兩種形式,最大堆和最小堆。兩個堆都是通過父子元素的關係確定的。對於這兩種形式,我們能且僅能確定的是根元素分別是陣列中的最大值和最小值,這也是堆排序的基礎。
乙個堆中結點的高度是該結點到葉結點最長簡單路徑上邊的數目。下面幾個是堆排序中的基本過程。
max-heapity(a, i)
l=left(i)
r=right(i)
if l<=a.heap_size and a[l]>a[i]
largest=l
else
largest=i
if r<=a.heap_size and a[r]>a[i]
largest=r
if largest!=i
exchange a[i] with a[largest]
max-heapity(a, largest)
我們可以用自底向上的方法利用過程max-heapity把乙個大小為n=a.length的陣列a[1, n]轉換為最大堆。
build-max-heap(a)
a.heap_size=a.length
for i=a.length/2 downto 1
max-heapity(a, i)
這裡的迴圈不變數是:在第2~3行中每乙個for迴圈開始的地方,結點i+1, i+2, …, n都是乙個最大堆的根結點。
heapsort(a)
build-max-heap(a)
for i=a.length downto 2
exchange a[i] with a[1]
a.heap_size=a.heap_size-1
max-heapity(a, 1)
演算法導論 第六章《堆排序》
本章開始介紹了堆的基本概念,然後引入最大堆和最小堆的概念。全章採用最大堆來介紹堆的操作,兩個重要的操作是調整最大堆和建立最大堆,接著著兩個操作引進了堆排序,最後介紹了採用堆實現優先順序佇列。二叉 堆資料結構是一種陣列物件,它可以被視為一棵完全二叉樹。除了最底層外,該樹是完全充滿的,而且是從左到右填充...
演算法導論 第六章 堆排序
二叉 堆資料結構是一種陣列物件,如下圖所知,他可以被視為一顆完全二叉樹。其有如下性質 1 對於i節點 i表示下標 其父節點為li 2 左孩子節點為2i,右孩子節點為2i 1 2 最大堆滿足 a parent i a i 最小堆滿足 a parent i a i 3 堆的高度為 lgn 4 子陣列元素...
演算法導論第六章 堆排序
堆排序 主要是二叉堆,是乙個陣列,可以近似看作是一棵完全二叉樹。最壞情況執行時間為 n log n 主要性質 1.對於任意乙個下標index,書上寫的是左子女的下標為 2 index,右子女為 2 index 1 但是在實際程式設計中,下標是從0開始的,所以下標的變化應該為 左子女為2 index ...