上一節(Java實現隊列——順序隊列、鏈式隊列)咱們使用數組實現了順序隊列,可是在tail == n
時會有數據搬移操做,這樣入隊操做性能就會受到影響。這裏咱們使用循環隊列的解決思路。git
顧名思義,首尾相連就造成了循環隊列,以下圖所示: github
實現循環隊列最關鍵的部分是肯定隊列什麼時候爲空什麼時候滿。在用數組實現的非循環隊列中,隊滿的判斷條件是tail == n,隊空的判斷條件是head == tail。在循環隊列中,隊列爲空的判斷條件仍然是head == tail,但隊列滿的判斷條件有所更改,是( tail + 1 ) % capacity == head
。 另一點須要注意的是,當隊列滿時,tail指針指向的位置其實是沒有存儲數據的,因此會浪費一個數組的存儲空間。數組
代碼實現以下:bash
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 +
'}';
}
}
複製代碼
測試代碼:ide
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傳送門 github.com/tinyvampire…ui
gitee傳送門 gitee.com/tinytongton…this
參考: 隊列:隊列在線程池等有限資源池中的應用spa