隊列是一種先進先出的數據結構,跟棧類似,隊列是一種操作受限的線性表。
隊列同樣可以由數組和鏈表來實現。
隊列需要兩個指針:一個是 head 指針,指向隊頭;一個是 tail 指針,指向隊尾。
## 順序隊列
順序隊列存在一個問題, tail 指針移動到數組最大下標時,即使數組中還有空閑空間,也無法繼續往隊列中添加數據了。
解決方法是在入隊列時,如果沒有空閑空間,就觸發一次搬運,將 head 到 tail 之間的數據,整體搬運到數組的 0 到 tail - head 位置。
## 鏈式隊列
鏈式隊列與順序隊列的區別是沒有容量限制,在請求排隊的場景下,如果排隊的請求數量過多,請求處理的響應時間會過長。
## 循環隊列
循環隊列是為了解決順序隊列在 tail == n 時,需要數據搬運操作的問題。
隊列為空時可以根據 head == tail 來判斷。循環隊列滿時,tail 指針位置不存儲數據,所以隊滿判斷公式為:
(tail + 1) % n = head
## 阻塞和并發隊列
阻塞隊列在隊列為空的時候,從隊頭取數據會被阻塞,直到隊列中有數據才會返回;如果隊列已經滿了,插入數據操作會被阻塞,直到隊列中有空閑的位置后再插入,然后再返回。
在考慮線程安全時,需要用到并發隊列,并發隊列同一時刻只允許一個插入操作,但是允許多個讀操作。