只能在表的一端進行插入,另一端進行刪除,且具有先進先出原則的線性表稱為佇列。
若用 s=(
a1,a
2,a3
,...
,an)
s=(a_1,a_2,a_3,...,a_n)
s=(a1
,a2
,a3
,...
,an
) 表示佇列,則:
佇列常見的兩種操作:
限定插入和刪除操作在表的兩端進行的線性表稱為雙端佇列。
雙端佇列又可以分為:
佇列基本操作用順序儲存方式儲存的佇列稱為順序佇列。
元素入隊只需將元素新增到佇列的最後乙個位置即可,但元素出隊時隊頭元素的位置如何變化?
出於空間、時間效率考慮,暫時採用犧牲空間換取時間的方式,採用方式 1 來設定隊頭 。
佇列指標的設定及隊空判斷:
順序佇列的初始化
順序佇列的入隊
順序佇列之出隊將隊頭與隊尾連線形成閉環的佇列稱為迴圈佇列。
迴圈佇列隊滿時便不能再新增新的元素,若 fro
ntfront
fron
t 和 rea
rrear
rear
指標的定義與順序佇列中相同,則出現 fro
nt==
rear
front == rear
front=
=rea
r 時無法判斷佇列是滿還是空的情況,所以如何判斷隊滿呢?
隊空、隊滿、佇列元素個數判斷:
迴圈佇列的初始化
迴圈佇列的入隊
迴圈佇列之出隊用鏈結儲存方式實現的佇列稱為鏈式佇列。
鏈式佇列的指標:
鏈式佇列的初始化
鏈式佇列的入隊
將元素插入到隊尾:
鏈式佇列之出隊
刪除鍊錶的首元結點:
迴圈佇列和鏈式佇列的比較
時間複雜度:迴圈佇列和鏈式隊列入隊、出隊的時間複雜度都為 o(1
)o(1)
o(1)
空間上複雜度:
順序佇列與鏈式佇列的比較
順序佇列有固定的儲存空間,不適用於儲存空間很大,刪除插入很頻繁的操作,此時順序佇列的空間利用率很低;反之,鏈式佇列適用此情況。
順序佇列的訪問簡單,對佇列內部元素的訪問便捷;鏈式佇列元素需便利整個鍊錶。
應用例項
應用場景:雙端佇列最常用的地方就是實現乙個長度動態變化的視窗或者連續區間,而動態視窗這種資料結構在很多題目裡都有運用。
1.滑動視窗最大值
例題:給定乙個陣列 nums,有乙個大小為 k 的滑動視窗從陣列的最左側移動到陣列的最右側。你只可以看到在滑動視窗 k 內的數字,滑動視窗每次只向右移動一位。返回滑動視窗最大值。
說明:可以假設 k 總是有效的,1 ≤ k ≤ 輸入陣列的大小,且輸入陣列不為空。
示例:給定乙個陣列以及乙個視窗的長度 k,現在移動這個視窗,要求列印出乙個陣列,陣列裡的每個元素是當前視窗當中最大的那個數。
輸入:nums = [1, 3, -1, -3, 5, 3, 6, 7],k = 3
輸出:[3, 3, 5, 5, 6, 7]
解題思路:
思路 1:移動視窗,掃瞄,獲得最大值。假設陣列裡有 n 個元素,演算法複雜度就是 o(n
)o(n)
o(n)
。這是最直觀的做法。
思路 2:利用乙個雙端佇列來儲存當前視窗中最大那個數在陣列裡的下標,雙端佇列新的頭就是當前視窗中最大的那個數。通過該下標,可以很快地知道新的視窗是否仍包含原來那個最大的數。如果不再包含,我們就把舊的數從雙端佇列的頭刪除。
因為雙端佇列能讓上面的這兩種操作都能在 o(1) 的時間裡完成,所以整個演算法的複雜度能控制在 o(n
初始化視窗 k=3,包含 1,3,-1,把 1 的下標壓入雙端佇列的尾部;
把 3 和雙端佇列的隊尾的資料逐個比較,3 >1,把 1 的下標彈出,把 3 的下標壓入隊尾;
-1<3,-1 壓入雙端佇列隊尾保留到下一視窗進行比較;
3 為當前視窗的最大值;
視窗移動,-3 與隊尾資料逐個比較,-3
3 為當前視窗的最大值;
視窗繼續移動,5>-3,-3 從雙端佇列隊尾彈出;
5>-1,-1 從隊尾彈出;
3 超出當前視窗,從佇列頭部彈出;
5 壓入佇列頭部,成為當前視窗最大值;
繼續移動視窗,操作與上述同理。
視窗最大值只需讀取雙端佇列頭部元素。
《資料結構與演算法之美》06 佇列
一 概念 佇列 先進者先出。與棧一樣,也是一種受限的線性表,同樣有兩個基本操作 入隊和出隊。二 佇列實現 佇列有兩種實現方式 順序佇列和鏈式佇列。順序佇列 用陣列實現的佇列叫作順序佇列。需要兩個指標 head指標和 tail 指標,分別指向隊頭和隊尾。隨著入隊和出隊操作,head和 tail 會移到...
資料結構5 佇列
5.1簡介 佇列 queue 和堆疊一樣是一種有序鍊錶,屬於抽象資料型別。不同在於是先進先出 first in,first out,fifo 堆疊只需要乙個top指標指向堆疊頂端即可,但是佇列必須使用front和rear兩個指標分別指向佇列的前端和尾端。基本操作 1 create 建立空佇列 2 a...
資料結構(二) 佇列
一 佇列定義 佇列是限定在一端進行插入,另一端進行刪除特殊線性表。二 佇列基本操作 入隊出隊 三 佇列例題 1.例1 舞伴配對問題 分析 這一題是一道經典的取模運算,每一次將編號往前加一位,到達n就取模。include include include include int main return ...