《演算法導論》學習筆記(1) 堆與堆排序

2021-06-20 10:03:36 字數 2049 閱讀 8378

堆排序( heapsort )是指利用「堆」這種資料結構

所設計的一種排序演算法

。堆是一種資料結構,是乙個陣列。它可以被看成乙個近似的完全二叉樹,樹上的每乙個結點對應陣列中的乙個元素。除了最底層外,即葉子結點,該樹是完全充滿的,而且是從左到右填充。

最大堆的每個結點都要滿足堆的性質,此外還有其他的約束:堆中的最大元素存放在根結點中,並且在任一子樹中,該子樹所包含的所有結點的值都不大於該子樹根結點的值。

堆排序就是利用最大堆的性質來排序。大致步驟如下:

①建最大堆

②將根結點(最大元素)與最後乙個結點的元素互換,並將剩下的結點維護最大堆的性質。

③重複步驟②,直到將每個元素排完序。

下面就講解幾個重要過程:

維護最大堆的性質:maxheapify

傳入引數:待排序陣列、需要維護的下標、當前堆的大小。返回值:空

每次在傳入引數的下標、該下標的左、右孩子結點三者中選出最大的元素。如果最大元素是該下標,則滿足最大堆性質,結束。否則,需要將父親與最大的孩子交換位置,使得當前下標及其左右孩子滿足最大堆的性質。之後遞迴呼叫,使得整個子樹都滿足最大堆的性質。

特別需要注意,陣列的大小和堆的大小是不一樣的概念。堆的大小表示有多少個堆元素儲存在陣列中。在進行堆排序的過程中,每次需要把根結點元素與最後乙個元素交換,這樣堆的大小每次就會減一。而陣列大小是不會變的。也就是:

0 ≤ 堆的大小 ≤ 陣列的大小

建最大堆:buildmaxheap

傳入引數:待排序陣列、當前堆的大小。返回值:空

只需保證所有的非葉子結點滿足最大堆的性質即可。非葉子結點的下標為從0到堆大小 / 2(向下取整)。

堆排序:heapsort

傳入引數:待排序陣列、當前堆的大小。返回值:空

首先建堆,然後每次去除根結點元素(最大元素),然後維護最大堆的性質。如此迴圈,直到所有元素排序完畢。

實現**如下:

#include using namespace std;

typedef int elemtype;

int getleftchild( int i ) //返回左孩子下標。注:陣列從位置0開始

int getrightchild( int i ) //返回右孩子下標。注:陣列從位置0開始

void swap( elemtype *a, elemtype *b ) //交換兩個元素

/* 維護最大堆的性質。

* 引數:待排序陣列、需要維護的下標、當前堆的大小

* 返回值:空

*/void maxheapify( elemtype *a, int i, int num )

}/* 建最大堆

* 傳入引數:待排序陣列、當前堆的大小

* 返回值:空

*/void buildmaxheap( elemtype *a, int num )

/* 堆排序

* 待排序陣列、當前堆的大小

* 返回值:空

*/void heapsort( elemtype *a, int num )

}int main()

; heapsort( a, 10 );

for( int j=0; j<10; j++ )

cout << a[j] << " ";

cout << endl;

return 0;

}

時空複雜度:由於每次重新恢復堆的時間複雜度為o(logn),共n - 1次重新恢復堆操作,再加上前面建立堆時n / 2次向下調整,每次調整時間複雜度也為o(logn)。二次操作時間相加還是o(n * logn)。故堆排序的時間複雜度為o(n * logn)。

由於建初始堆所需的比較次數較多,所以堆排序不適宜於記錄數較少的檔案。

堆排序是就地排序,輔助空間為o(1), 它是不穩定的排序方法。

演算法導論 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...

《演算法導論》學習分享 6 堆排序

堆排序也是一種時間複雜度為o n lg n omicron n lg n o nlgn 的排序演算法,但是與歸併排序不同的是堆排序是一種原址排序,也就是說排序過程只是交換資料的位置。堆是乙個陣列,儲存乙個近似完全二叉樹,樹上的每個結點對應陣列中的乙個元素,陣列第乙個元素儲存根節點,第i個元素的左孩子...

演算法導論讀書筆記(6)堆排序

複雜度o nlgn 原址排序 集插入排序和歸併排序兩者的優點 計算給定節點下標i的父,左孩子,右孩子的下標 parent i return i 2 left i return 2i right i return 2i 1 最大堆 堆中最大元素存放在根結點 最小堆 堆中最小元素存放在根結點 從a i ...