Java陣列實現迴圈佇列
阿新 • • 發佈:2018-12-10
Java陣列實現迴圈佇列
上一節(Java實現佇列——順序佇列、鏈式佇列)我們使用陣列實現了順序佇列,但是在tail == n
時會有資料搬移操作,這樣入隊操作效能就會受到影響。這裡我們使用迴圈佇列的解決思路。
迴圈佇列
顧名思義,首尾相連就形成了迴圈佇列,如下圖所示:
實現迴圈佇列最關鍵的部分是確定佇列何時為空何時滿。在用陣列實現的非迴圈佇列中,隊滿的判斷條件是tail == n,隊空的判斷條件是head == tail。在迴圈佇列中,佇列為空的判斷條件仍然是head == tail,但佇列滿的判斷條件有所更改,是( tail + 1 ) % capacity == head
另外一點需要注意的是,當佇列滿時,tail指標指向的位置實際上是沒有儲存資料的,所以會浪費一個數組的儲存空間。
程式碼實現如下:
public class CircularQueue implements QueueInterface { private String[] values;// 容器 private int capacity = 0;// 容量 // head 表示隊頭下標,tail表示對尾下標 private int head = 0; private int tail = 0; public CircularQueue(int capacity) { values = new String[capacity]; this.capacity = capacity; } @Override public Boolean enqueue(String value) { // 佇列滿了 if ((tail + 1) % capacity == head) { return false; } values[tail] = value; tail = (tail + 1) % capacity; return true; } @Override public String dequeue() { // 如果head == tail 表示佇列為空 if (head == tail) { return null; } String ret = values[head]; head = (head + 1) % capacity; return ret; } @Override public String toString() { return "CircularQueue{" + "values=" + Arrays.toString(values) + ", capacity=" + capacity + ", head=" + head + ", tail=" + tail + '}'; } }
測試程式碼:
CircularQueue cq = new CircularQueue(10); System.out.println(cq); System.out.println(); //正常新增的資料 System.out.println("正常新增的資料:"); for (int i = 0; i < 9; i++) { System.out.println("cq.enqueue():" + cq.enqueue("" + i + i + i)); System.out.println(cq); } System.out.println(); // 佇列滿了以後新增資料 System.out.println("佇列滿了以後新增資料:"); System.out.println("cq.enqueue():" + cq.enqueue("aaa")); System.out.println(cq); System.out.println(); // 清空佇列 System.out.println("清空佇列:"); for (int i = 0; i < 9; i++) { System.out.println("cq.dequeue():" + cq.dequeue()); System.out.println(cq); } System.out.println(); // 佇列清空以後,繼續清空 System.out.println("佇列清空以後,繼續清空:"); System.out.println("cq.dequeue():" + cq.dequeue()); System.out.println(cq);
輸出結果:符合期望
CircularQueue{values=[null, null, null, null, null, null, null, null, null, null], capacity=10, head=0, tail=0}
正常新增的資料:
cq.enqueue():true
CircularQueue{values=[000, null, null, null, null, null, null, null, null, null], capacity=10, head=0, tail=1}
cq.enqueue():true
CircularQueue{values=[000, 111, null, null, null, null, null, null, null, null], capacity=10, head=0, tail=2}
cq.enqueue():true
CircularQueue{values=[000, 111, 222, null, null, null, null, null, null, null], capacity=10, head=0, tail=3}
cq.enqueue():true
CircularQueue{values=[000, 111, 222, 333, null, null, null, null, null, null], capacity=10, head=0, tail=4}
cq.enqueue():true
CircularQueue{values=[000, 111, 222, 333, 444, null, null, null, null, null], capacity=10, head=0, tail=5}
cq.enqueue():true
CircularQueue{values=[000, 111, 222, 333, 444, 555, null, null, null, null], capacity=10, head=0, tail=6}
cq.enqueue():true
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, null, null, null], capacity=10, head=0, tail=7}
cq.enqueue():true
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, null, null], capacity=10, head=0, tail=8}
cq.enqueue():true
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=0, tail=9}
佇列滿了以後新增資料:
cq.enqueue():false
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=0, tail=9}
清空佇列:
cq.dequeue():000
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=1, tail=9}
cq.dequeue():111
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=2, tail=9}
cq.dequeue():222
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=3, tail=9}
cq.dequeue():333
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=4, tail=9}
cq.dequeue():444
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=5, tail=9}
cq.dequeue():555
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=6, tail=9}
cq.dequeue():666
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=7, tail=9}
cq.dequeue():777
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=8, tail=9}
cq.dequeue():888
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=9, tail=9}
佇列清空以後,繼續清空:
cq.dequeue():null
CircularQueue{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, null], capacity=10, head=9, tail=9}
完整程式碼請檢視
專案中搜索SingleLinkedList即可。
github傳送門 https://github.com/tinyvampirepudge/DataStructureDemo