演算法導論學習之堆 堆排序 堆構成優先佇列

2021-06-29 01:29:59 字數 2193 閱讀 4648

注:堆分為最大堆和最小堆兩種,下面我們討論的堆都是指的最大堆,最小堆的性質與其是類似的。

堆資料結構是一種陣列物件,可以被視為一棵完全二叉樹(這棵二叉樹除最後一層外,其餘每層都是填滿的);我們用乙個陣列來儲存乙個堆,表示堆的陣列有兩個屬性:length[a]表示的是陣列中的元素個數,headsize[a]表示堆中元素個數(也就是說陣列中的元素不一定都是堆中的元素)。

下面不加證明的給出一些堆的性質:

對於任何乙個節點,其父節點為i/2(i>1);左兒子:2*i,右兒子:2*i+1;

對於最大堆每個節點滿足:a[parent[i]]>=a[i]

含n個元素堆的高度為lgn

含n個元素堆的葉子節點的編號為:n/2+1,n/2+2,……,n。

一.堆的調整函式—保持堆的性質

考慮這樣一種情況,如果對於節點i,其左右子樹都是乙個合法的大根堆,但是節點i不滿足堆的性質,那麼我們可以通過調整使得以i為根節點的樹滿足堆的性質。那麼具體的調整過程是怎樣的呢?我們令largest表示a[i],a[i*2],a[2*i+1]中最大的那個,如果largest不是i那麼我們就交換a[i]和a[largest]並且遞迴的進入到以largest為根節點的子樹中繼續進行調整。具體的**實現如下:

void maxheadfly(int *a,int i,int headsize)

}

二.堆的建立

堆的建立其實就是乙個不斷呼叫調整函式的過程。我們知道堆的葉子節點可以看成只含有乙個元素合法的大根堆,這樣如果我們從第乙個非葉子節點開始依次呼叫調整函式,就可以保證被調整的節點的左右子樹都是合法的大根堆,進而可以保證調整得到的樹也是合法的大根堆。具體的**實現如下:

void buildmaxhead(int *a,int n)

三.堆排序

顧名思義堆排序就是利用堆的性質對陣列進行排序,對於乙個堆來說我們能利用的性質就是其根節點中的元素是最大的,這次每次我們都可以將a[1]與a[headsize]進行交換,交換以後headsize的值減1,並且呼叫maxheadfly(a,1,headsize)對堆進行調整,使得a[1]又變成剩下元素中最大的,然後繼續這個過程。最後得到乙個有序的陣列。堆排序的時間複雜度是nlgn;具體的**實現如下:

void headsort(int *a,int n)

}

#include

#include

#include

using

namespace

std;

int swp(int &a,int &b)

void maxheadfly(int *a,int i,int headsize)

}void buildmaxhead(int *a,int n)

void headsort(int *a,int n)

}int main()

四.優先佇列

對於一般的佇列來說,滿足先進先出的性質(隊尾入隊,對首出隊),但對於優先佇列來說,每次都是最大的/最小的元素出隊。堆可以實現優先佇列的基本操作,利用的也是堆的性質。優先佇列一些具體的函式操作及其原理見下面的**。

#include

#include

#include

using namespace std;

#define inf 0x3f3f3f3f

///一般的佇列滿足先進先出的性質,而優選佇列不同,其

///總是最大的/最小的先出隊。借助於堆的性質,我們可以

///在lgn的時間內實現優選佇列的任何操作

void swp(int &a,int &b)

void maxheadfly(int *a,int i,int headsize)///堆調整函式

}void buildmaxhead(int *a,int n) ///建立乙個最大堆

///以下為優先佇列的操作

int maxnum(int *a) ///取出最大的元素

void increasekey(int *a,int x,int k)

}int extractmax(int *a,int &headsize)

void insert(int *a,int &headsize,int x)

int main()

演算法導論之五堆排序

堆排序的時間複雜度是,與插入排序相似,堆也具有空間原址性,即任何時候都只需要常數個額外的元素空間儲存臨時資料。1.堆簡介 1 堆是乙個陣列,表示堆的陣列a包括兩個屬性 a.length表示陣列元素的個數,a.heap size表示有多少個堆元素儲存在該陣列中。給定一結點的下標i,可以得到其父結點 左...

演算法導論 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個元素的左孩子...