1. 程式人生 > >【小白學演算法】3. 迴圈佇列

【小白學演算法】3. 迴圈佇列

在[上一章](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