堆排序和優先順序佇列

2022-08-28 15:57:16 字數 2573 閱讀 1244

堆排序和優先順序佇列

堆排序:和合併排序一樣,時間複雜度為o(nlgn);同時和插入排序一樣,在原序列中進行;這樣堆排序集合了合併排序和插入排序的優點。

堆排序的另乙個特點是利用了"堆"這種資料結構. 堆資料結構還不止在堆排序中有用,還可以構成乙個有效的優先佇列.

堆: 是一種資料結構,也是一種陣列物件,如圖 1-1所示: 

圖 1-1 最大堆(**《演算法導論》)

如上圖1-1 所示, 可以被看成一棵完全二叉樹,二叉樹的的每個節點和陣列中存放該節點的那個元素對應.在使用"堆"資料機構的時候,其實並不需求真正構建一棵完全二叉樹, 資料的儲存依然是在乙個陣列中,操作也在陣列中,只是陣列中資料的存放,位置關係如完全二叉樹所示,我們在構造堆的時候其實是在構建陣列中資料的關係. 上圖所示乙個最大堆(父節點大於兩個子節點), 最小堆同理.

由於我們將陣列中的資料關係對應成了一塊完全二叉樹,所以對陣列的各種操作時間複雜度也應該和完全二叉樹操作向對應,即o(nlgn). 下文所以的堆即代指"最大堆"。

堆排序

根據堆的性質,父節點大於子節點,那麼根節點一定是最大的,繼而陣列中第乙個資料也應該是最大的. 根據氣泡排序和選擇排序的原理, 如果將每次陣列中的第乙個元素和最後乙個元素進行交換,再讓第乙個到倒數第二個形成的新陣列重新形成最大堆,再次將新陣列第乙個和最後乙個交換;需要重新建堆的陣列長度不斷減小.如此迴圈下去,最後原數組成了乙個有小到大的有序序列.

根據上面的論述,如何讓無序的元素,構建成乙個符合(最大/最小)堆性質的堆才是關鍵.

保持堆(最大堆)性質原理: 將父節點和兩個子節點進行比較,找到那個最大;如果父節點最大,該節點符合最大堆性質;如何是兩個子節點中某個最大,將最大子節點和父節點位置進行交換; 在檢視新的子節點作為父節點是否符合最大堆的性質,以此迴圈.

**如下:

1

//子節點和父節點在陣列中位置的對應關係(陣列從0開始)

2int parent(inti)3

6//父節點和左子節點在陣列中的位置對應關係

7int left(inti)8

11//

父節點和右子節點在陣列中的位置對應關係

12int right(int

i)13

1617

//保持最大堆性質,迴圈控制的形式

18void maxheapify(int a, int i,int

length)

193940}

4142

//保持最小堆性質,遞迴的形式

43void minheapify(int a, int i,int

length)

4465

66 }

建堆以及堆排序演算法: 

堆排序的基本原理就是對乙個無序陣列建立堆關係,再利用堆的性質不斷重陣列中查詢最值元素.

建堆的**如下:

1

void buildmaxheapify(int a, int

length)

2

堆排序的演算法**如下: 

1

void heapsort(int a,int

length)216

17 }

優先順序佇列優先順序佇列分為最大優先順序佇列和最小優先順序佇列.(應用舉例摘於《演算法導論》)

最大優先順序佇列應用:其一,一台分時計算機上進行作業排程,如何從具有優先順序標示的佇列中選擇優先順序最高的任務.

最小優先順序佇列應用: 其一, 被用在基於事件驅動的模擬器中. 在這種應用中,佇列中的各項是要模擬的事件,每乙個都有乙個發生時間作為關鍵字。事件模擬按照各事件的發生時間的順序進行,因為模擬某一事件可能導致稍後對其他事件的模擬。模擬程式都使用extract-min來選擇下乙個事件,而使用insert將乙個新事件插入佇列中。

最大優先順序佇列提取操作**如下:

1

int heapextractmax(int a, int

length)214

15return

max;

16 }

最大優先順序佇列提高或減小優先順序操作**如下:

1

void heapincreasekey(int a,int i,int

key)29

else

1019}20

}2122//

減小某一元素的關鍵字

23void heapdecreasekey(int a,int i,int key,int

length)

2431

else

3243

else

445152}

53}5455 }

最大優先順序佇列插入新元素操作**如下:

1

void maxheapinsert(int a,int key,int

length)

2

堆排序和優先順序佇列priority queue

堆 堆是完全二叉樹,便於用array來儲存堆的所有節點 堆儲存在下標為0開始計數的陣列中,因此在堆中給定下標為i的結點時 如果i 0 結點i是根節點,沒有雙親節點 否則結點i的雙親結點為結點 i 1 2。如果2 i 1 n 1 則結點i無左孩子,否則結點i的左孩子為結點2 i 1。如果2 i 2 n...

堆排序 最大優先順序佇列

author bigballon note max priority queue date 2013.11.21 一篇好文章 include using namespace std void my swap int x,int y void max heapify int a,int i,int l...

二叉堆 堆排序 優先順序佇列

二 堆排序 三 優先順序佇列 四 參考資料 堆排序 用 來實現優先順序佇列 二叉堆本質上是一棵完全二叉樹,分為最大堆和最小堆兩種 二叉堆的根節點叫做堆頂。二叉堆本質雖然是完全二叉樹,但是底層沒有使用鍊錶 鏈式儲存 實現,而是使用陣列 順序儲存 實現。根據二叉樹的性質,假設父節點的索引為i,則左孩子所...