【小白學演算法】3. 迴圈佇列
阿新 • • 發佈:2021-03-14
在[上一章](https://www.cnblogs.com/pingguo-softwaretesting/p/14509117.html)中,使用了陣列模擬了佇列。但是留下的問題是,把資料取完後,再往裡加資料就不行了。
### 一、假溢位
這是因為陣列的末尾已經被佔用了,入隊會繼續在陣列後面增加,於是產生陣列越界。
但是實際上,數組裡是有空閒位置的,這種也可以叫“假溢位”。
![](https://img2020.cnblogs.com/blog/1268169/202103/1268169-20210313211154071-357742303.png)
為了解決“假溢位”的問題,於是乎有了迴圈佇列。
既然陣列後面滿了,頭部有空,那繼續加進來的元素從頭開始放即可。
接著上圖,這時候有a6入隊,於是rear的下標指向a6的下一個元素位置,看起來沒什麼問題。
![](https://img2020.cnblogs.com/blog/1268169/202103/1268169-20210313211241040-576390048.png)
但是繼續有新的元素a7入隊的時候,因為front一直沒變,這時候rear指標跟front就重合了,也就是說此時`front=rear`。
![](https://img2020.cnblogs.com/blog/1268169/202103/1268169-20210313211452152-27254263.png)
可是在上一章的程式碼裡,我們是用`front=rear`來判斷是否為空陣列的。
```
// 判斷佇列是否為空
public boolean isEmpty() {
return rear == front;
}
```
現在是相等了,條件滿足,但是陣列是滿的。
### 二、迴圈佇列判斷是空是滿
這種情況看起來確實比較辣手,那如果不讓這種情況出現不就可以了麼?
假設,我們讓陣列始終保留一個元素空間,也就是讓rear指向佇列中最後一個元素的後一個位置。
比如,當a6放入之後,此時就當做佇列已經滿了,這樣的話就不會出現上述的情況了。
![](https://img2020.cnblogs.com/blog/1268169/202103/1268169-20210313211628336-1135799305.png)
為了實現這種思路,front也需要做調整。在上一章中,front初始位置是指在了隊頭元素的前一個,現在我們讓它就指在
第一個元素。佇列的最大尺寸還是maxSize,那麼,**現在判斷佇列滿的條件就可以是這樣**:`(rear+1)%maxSize = front`
驗證一下,下面的2種佇列滿情況:
![](https://img2020.cnblogs.com/blog/1268169/202103/1268169-20210313211043774-1991219196.png)
* 左圖:佇列中,maxSize=5,front=0,rear=4,判斷(4+1)% 5=0=front,佇列已滿
* 右圖:佇列中,maxSize=5,front=2,rear=1,判斷(1+1)% 5=2=front,佇列已滿
繼續驗證一下,佇列沒滿的情況:
![](https://img2020.cnblogs.com/blog/1268169/202103/1268169-20210313213850535-1189249998.png)
* 佇列中,maxSize=5,front=2,rear=0,判斷(0+1)% 5=1≠front,佇列未滿
### 三、迴圈佇列的長度計算
佇列的長度,也就是說佇列中實際存了多少個元素。
此時需要考慮rear與front之間的三種情況:
1. rear=front
2. rear>front
3. rearfront,此時佇列的長度為:rear-front
![](https://img2020.cnblogs.com/blog/1268169/202103/1268169-20210313215935809-698188075.png)
第三種,rear