優先佇列:該資料結構支援兩種操作:刪除最大元素和插入元素
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 概念 優先順序佇列,顧名思義,就是一種根據一定優先順序儲存和取出資料的佇列。它可以說是佇列和排序的完美結合體,不僅可以儲存資料,還可以將這些資料按照我們設定的規則進行排序。優先順序佇列是堆的一種常見應用。有最大優先順序佇列 最大堆 和最小優先順序佇列 最小堆 優先順序佇列是一種維護有一組元素構成...