堆排序是一種基於比較排序的另一種排序演算法,它採用了一種近似完全二叉樹的二叉堆資料結構。演算法實現相容了插入排序的空間原址性(即只需要有限個額外的儲存空間)和歸併排序的優良時間複雜度。
偽**如下:
heapsort(a)
build-max-heap(a)
for i = a.length downto 2
exchange a[1] with a[i]
a.heap-size = a.heap-size - 1
max-heapify(a, 1)
build-max-heap(a)
a.heap-size = a.
length
fori = floor(a.
length / 2) downto 1
max-heapify(a, i)
max-heapify(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[largest]
largest = r
if largest != i
exchange a[i] with a[largest]
max-heapify(a, largest)
分析:
首先要明白什麼是二叉堆,它的左右孩子是什麼。
a.堆排序的核心子程式就是max-heapify(a, i),稱作最大堆的維護。輸入為陣列a,和乙個下標i,i的左孩子和右孩子都滿足最大堆的性質,但a[i]可能小於其孩子,於是需要重新定位a[i]的位置,使其保持最大堆的性質。**過程為:先找出a[i],a[left[i]],a[right[i]]的最大值,然後將最大值與a[i]交換。然後遞迴的交換,到最後每乙個節點i都滿足a[
left
(i)]
≤a[i
] ,a[
righ
t(i)
]≤a[
i]。b.堆排序首先要建立乙個最大堆。在子程式build-max-heap(a)中,由於a(n/2+1..n)中的元素都是樹的葉結點,所以只需要把前n/2個數插入到這個最大堆中,然後每插入乙個數進行最大堆維護,當這n/2個數插完後,所得的陣列就是乙個最大堆。
c.堆排序主程式,先把所要排序的陣列轉化成最大堆,由於根位置的數就是最大的數,所以每次取根上的數放在陣列的最後面,然後其餘n-1個數維護後又成為最大堆,再取此時根上的數,直到只剩最後乙個數,所得到的陣列就是排好序的陣列。
d.最大堆維護的時間複雜度為 t(
n)=o
(lgn
) ,因為每個孩子的子樹的大小至多為 2n
/3,節點左右孩子的高度至多差1,所以 t(
n)≤t
(2n/
3)+θ
(1) ,得出 t(
n)=o
(lgn
) 。建堆需要呼叫 n/
2 次堆維護,所以需要 o(
nlgn
) 。所以堆排序總時間為:呼叫一次建堆,n−
1 次堆維護。所以總共時間複雜度為 o(
nlgn
) 。
c++**實現
#include
using
namespace
std;
void max_heapify(int*, int, int);
void heapsort(int*, int);
int main()
; int length = sizeof(a)/sizeof(int);
int heap_size = length;
heapsort(a, heap_size);
for(int i = 0; i < length; i++)
cout
void max_heapify(int* a, int i, int heap_size)
}void heapsort(int* a, int heap_size)
for(int i = length-1; i > 0; i--)
}
排序之堆排序
這裡沒有對0號元素進行排序 堆排 public class heap public static void exec comparable array,int i,int j 下沉 private static void sink comparable array,int k,int n publi...
排序之堆排序
堆其實是一種完全二叉樹,從上到下從左到右,大頂堆的父節點大於其左右子節點,小頂堆的父節點小於其左右子節點 1 首先是進行heapify,建立堆 2 從下到上,從右到左的進行heapify構建有序的堆 3 進行排序,將堆頂父節點和底層最右邊的子節點互換,然後不斷重複以上步驟 1 heapify def...
排序之堆排序
利用堆這種資料結構進行排序的一種演算法,它是選擇排序的一種。我們可以把堆看成一棵完全二叉樹,這棵完全二叉樹滿足 大堆 每個節點的值大於等於孩子節點的堆 小堆 每個節點的值小於等於孩子節點的堆 代表堆的完全二叉樹的根結點的值是最值的,也是陣列的第乙個元素,將乙個無序序列調整為乙個堆,就可以找出這個序列...