迴圈佇列FIFO

2022-10-09 02:54:11 字數 2409 閱讀 5953

這裡的 fifo 是先入先出的意思,即誰先進入佇列,誰先出去。比如我們需要串列埠列印資料,當使用快取將該資料儲存的時候,在輸出資料時必然是先進入的資料先出去,那麼該如何實現這種機制呢?

首先就是建立乙個快取空間,這裡假設為 7 個位元組空間進行說明。

快取一開始沒有資料,並且用乙個變數 rear 指示下乙個存入快取的索引位址,這裡下乙個存放的位置就是 0,用另乙個變數 front 指示下乙個存入快取的索引位址,並且下乙個讀出資料的索引位址也是 0。目前佇列中是沒有資料的,也就是不能讀出資料,隊列為空的判斷條件在這裡就是兩個索引值相同。

現在開始存放資料:

在這裡可以看到佇列中加入了 5 個資料,並且每加入乙個資料後隊尾索引加 1,隊頭不變,這就是資料加入佇列的過程。但是快取空間只有 7 個,如何判斷佇列已滿呢?

如果只是先一次性加資料到佇列中,然後再讀出資料,那這裡的判斷條件顯然是隊尾索引為 6,但實際上是在加入資料的同時也可能出現有資料已出隊的情況,比如:

這個時候索引是 6,但是實際上還是有乙個索引為 0 的位置是空的,也就是實際上還是可以再加入乙個資料的。這個時候又該如何判斷是否佇列已滿呢?

通過以下演算法即可:

(rear + 1) % 7 == front

你可以發現這個演算法的巧妙。通過%運算將索引又從 6 返回到了 0 處,這是實現迴圈佇列的關鍵之處。通過該演算法就能知道佇列是否已滿了。佇列空的演算法就是隊頭隊尾索引相同。

front == rear

rear = (rear + 1) %7

這樣當 rear 等於 6 的時候下乙個索引就是 0 了。非常巧妙的實現了數值的迴圈。這個時候就出現了如下情況:

隊尾索引跑到了隊頭索引的前頭。並且周而復始,這就是迴圈佇列了,充分的利用了空間。

但你有沒有發現其實在有 7 個空間的情況下其實只能存放 6 個資料,另乙個資料空間是沒法使用的,為什麼呢?看看以下兩種情況:

這裡一種為隊列為空的情況,有一種佇列已滿的情況,這個時候到底是空還是滿的單靠這兩個變數是無法判斷的,這個時候就需要增加乙個變數指示佇列已滿的情況,並且需要加入判斷語句,降低了執行效率,所以建議採用留空的方式進行統一處理。

這樣入隊出隊操作都有了,也就算完成了基本操作,實際上有時候需要獲取整個佇列存放的數量,這時又涉及到了乙個有意思的公式:

(rear – front + 7) % 7

來看一看這個公式的巧妙性。當出現如下 rear 在後,front 在前這種正常情況時,只要兩種相減即可得到佇列的長度。

但實際上對於迴圈佇列來說 rear 在前,front 在後也是再正常不過的事情,如下:

這個時候又該如何獲取呢?就是利用上面的公式了。通過它就能適應這兩種情況。

通過了解這個公式,感受它的巧妙,又可以想到利用這個公式幹點其他的,比如在時間的獲取上,不管你計時變數設定得多麼大,總有乙個限度,總會出現計時溢位的情況,但實際上你只要獲取溢位時間內的時間即可,比如乙個 16 位變數,每 1ms 自加 1,你想獲取 100ms 的定時時間(小於 65535),正常情況下只需通過如下判斷即可準確獲取:

currenttime >= (time + 100)

currenttime 是變化的時間,time 是開始的時刻。但你開始的時刻是有可能是在 currenttime = 65435 的情況下的,currenttime 必然溢位,開始從零開始計時,這樣你這個條件滿足必須是 currenttime = 65535,也就是說你從 65435 – 0 - 65535,整整多了乙個溢位週期時間。而如果你使用上面的公式就即使計數器溢位了,也能獲取準確的定時時間。

(currenttime - time + 65535) % 65535 >= 100

只要佇列的每個元素設定乙個標誌,刪除這個標誌就代表這個佇列元素已刪除即可,而插入元素則就重新設定該標誌,表明你已經存放了資料,並將資料寫入對應的位置即可。當然這個標誌其實還可以用於標誌這個元素屬於什麼種類的資料,這樣就是將兩種功能結合了在乙個標誌內了,而你要做的就是實現他們之間的一一對應關係即可。

FIFO佇列和優先佇列

fifo佇列相當於一般的佇列 優先隊列為操作時有優先順序的佇列 1.標頭檔案 include 2.fifo佇列 queue 型別名 變數名 3.優先佇列 priority queue 型別名 變數名 1.預設優先順序為優先順序最高的先出隊,預設的int型別的優先佇列中先出隊的為佇列中較大的數。2.小...

FIFO佇列和優先佇列

fifo佇列 定義 先進先出的儲存結構 刪除時先刪最後乙個元素 queue 型別 q 增 q.push 元素值 在隊尾加入乙個元素 void刪 q.pop 刪除元素,刪除隊首元素 void改 查 q.size 返回佇列中剩餘元素個數 int q.empty 返回佇列是否為空 bool q.front...

Python佇列FIFO操作

設定乙個長度為n的佇列,當元素滿時候,就自動丟棄最先進入佇列的資料 from collections import deque q deque maxlen 3 print q print q print q 輸出 deque 1,2,3 maxlen 3 deque 2,3,4 maxlen 3 ...