Java數組實現循環隊列

Java數組實現循環隊列

上一節(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

相關文章
相關標籤/搜索