《演算法》筆記 2 4 優先佇列

2021-08-02 23:52:52 字數 2968 閱讀 7751

優先佇列:該資料結構支援兩種操作:刪除最大元素和插入元素

2.4.1 從n個輸入中找出最大的m個元素api

思考:從n個輸入中找出最大的m個元素, n很大,n也可以無界限

方法一:將輸入排序然後從中找出m個最大元素;

方法二:將每個新的輸入和已知的m個最大元素比較,除非m較小,否則這種比較的代價會非常高昂。

從n個輸入中找出最大的m個元素,所需成本:

排序演算法:時間複雜度nlogn,空間複雜度:n

呼叫初級實現的優先佇列:時間複雜度nm,空間複雜度:m

呼叫基於堆實現的優先佇列:時間複雜度nlogm,空間複雜度:m

2.4.2 初級實現

2.4.2.1 陣列實現(無序)

插入元素:基於下壓棧的**,insert()方法和棧的push()方法完全一樣。

刪除最大元素:新增一段類似於選擇排序的內迴圈的**,將最大元素和邊界元素交換後刪除,刪除和對棧的pop()方法實現一樣

與棧類似,可以加入調整陣列大小的**保證資料結構中的元素大於1/4又不會溢位

無序序列是解決這個問題的惰性方法,僅在必要的時候採取行動

2.4.2.2 陣列實現(有序)

插入元素:在insert()中新增**,將所有較大的元素向右移動一格,使陣列保持有序;

刪除最大元素:最大陣列經insert後在陣列一遍,刪除操作與pop()相同

有序序列是解決這個問題的積極方法,盡可能地未雨綢繆

2.4.2.3 鍊錶表示法

實現棧或者佇列可以在常數時間內完成所有操作

優先佇列的插入和刪除最大元素的時間複雜度如下:

有序陣列    insert():n   delmax:1

無序陣列    insert():1   delmax:n

堆          insert():logn   delmax:logn

理想        insert():1   delmax:1

2.4.3 堆的定義

二叉堆:每個元素都要保證大於等於另兩個特定位置的元素

堆有序:當一棵二叉樹的每個節點都大於等於它的兩個子節點時,稱它為堆有序

二叉堆表示:

使用完全二叉樹表示,只用陣列不用指標,根節點在位置1,它的子節點在位置2,3,字節點的子節點在位置4,5,6,7,依次類推。

二叉堆是一組能夠用堆有序的完全二叉樹排序的元素,並在陣列中按照層次儲存(不適用陣列的第乙個位置),以下將二叉堆簡稱為堆。

位置k的節點的父節點的位置為k/2下取整,子節點為2k和2k+1

2.4.4 堆的演算法

2.4.4.1 由下至上的堆有序化(上浮)

某個節點比它的父節點更大從而打破堆有序的狀態,這是採用上浮操作swim(int k)

迴圈進行如下操作:交換這個節點與它的父節點,直到節點不再大於它的父節點或節點已經是根節點

2.4.4.2 右上之下的對有序化(下沉)

某個節點比它的子節點更小從而打破堆有序的狀態,這是採用下沉操作sink(int k)

迴圈進行如下操作:交換它和它的兩個子節點中的較大者,直到它的子節點都比它更小或者到達堆的底部

插入元素:

1.    將新元素加入到陣列末尾

2.    增加堆的大小

3.    讓新元素上浮到合適的位置

刪除最大元素:

1.    從陣列頂端山區最大的元素

2.    將陣列的最後乙個元素放到頂端

3.    減小堆的大小

4.    讓這個元素下沉到合適的位置

基於堆的優先佇列**:書202頁

2.4.4.3 多叉堆

對於三叉堆:節點k的字節點是3k-1,3k,3k+1,父節點是(k+1)/3,

對於d叉堆類似,需要在樹高logn/logd  和  在d個子節點中找到最大者   的代價之間找到折中

2.4.4.4 調整陣列大小

新增乙個沒有引數的建構函式,在insert()中增加將陣列加倍的**

2.4.4.5

元素的不可變性

2.4.4.6

索引優先佇列

2.4.5 堆排序(根是小的,子節點是大的)

堆排序分兩個階段,堆的構造和下沉排序

2.4.5.1 堆的構造

用sink()方法構造子堆,構造完後是乙個有序堆,大的在上,小的在下,根節點是最大的元素。

方法:從陣列的一半開始到位置1掃瞄元素,呼叫sink()方法

2.4.5.2 下沉排序

將最大的元素a[1](根節點)與a[n]交換,再用sink()方法調整a[1]到a[n-1]的堆有序;

再將最大的元素a[1](根節點)與a[n-1]交換,用sink()方法調整a[1]到a[n-2]的堆有序;

如此重複直到堆變空

堆排序**如下:

public static void sort(comparable a)

while(n>1)

}

2.4.5.3 先下沉後上浮

可以通過免去檢查元素是否到達正確位置來節省時間

方法:下沉中直接提公升較大的子節點,直至到達堆底,再使該元素上浮到正確的位置

效果:可以將比較次數減少一半

應用場景:需要額外的空間,用於比較操作代價高的情況

堆排序是同時最優第利用空間和時間的方法,在現代應用程式中越來越重要

演算法(第4版) Chapter 2 4 優先佇列

algorithms fourth edition written by robert sedgewick kevin wayne translated by 謝路雲 chapter 2 section 4 優先佇列 定義 當一棵二叉樹的每個結點都大於等於它的兩個子節點時,它稱為堆有序 相應地,在堆...

演算法筆記(JavaScript版) 優先佇列

優先佇列是一種抽象資料型別,最重要的操作是刪除最大元素和插入元素。用長度為n 1的陣列pq來表示乙個大小為n的堆,堆元素放在pq 1 至pq n 中,不使用pq 0 function maxpq this.insert function v this.delmax function 由下至上的堆有序...

演算法之優先佇列

1 概念 優先順序佇列,顧名思義,就是一種根據一定優先順序儲存和取出資料的佇列。它可以說是佇列和排序的完美結合體,不僅可以儲存資料,還可以將這些資料按照我們設定的規則進行排序。優先順序佇列是堆的一種常見應用。有最大優先順序佇列 最大堆 和最小優先順序佇列 最小堆 優先順序佇列是一種維護有一組元素構成...