Java實現隊列——順序隊列、鏈式隊列

Java實現隊列——順序隊列、鏈式隊列

概念

先進者先出,這就是典型的「隊列」。(First In, First Out,FIFO)。git

咱們知道,棧只支持兩個基本操做:入棧push()和出棧pop()。隊列跟棧很是類似,支持的操做也頗有限,最基本的操做也是兩個:入隊和出隊。入隊 enqueue(),讓一個數據到隊列尾部;出隊 dequeue(),從隊列頭部取一個元素。github

棧和隊列

因此,隊列跟棧同樣,也是一種操做受限的線性表數據結構。數組

跟棧相似,用數組實現的隊列叫作順序隊列,用鏈表實現的隊列叫作鏈式隊列。下面咱們看下如何用Java代碼如何實現。bash

順序隊列

代碼以下:數據結構

public class QueueBasedArray implements QueueInterface {
    private String[] values;// 數組
    private int capacity = 0;// 數組容量
    private int head = 0;// 頭部下標
    private int tail = 0;// 尾部下標

    public QueueBasedArray(int capacity) {
        values = new String[capacity];
        this.capacity = capacity;
    }

    @Override
    public Boolean enqueue(String value) {
        // tail == capacity 表示隊列末尾沒有空間了
        if (tail == capacity) {
            // tail == capacity && head == 0 表示整個隊列都佔滿了。
            if (head == 0) {
                return false;
            }
            // 數據搬移
            for (int i = head; i < tail; i++) {
                values[i - head] = values[i];
            }
            // 搬移完成後更新 head 和 tail
            tail -= head;
            head = 0;
        }
        values[tail] = value;
        tail++;
        return true;
    }

    @Override
    public String dequeue() {
        // 若是 head == tail 表示隊列爲空
        if (0 == tail) {
            return null;
        }
        String result = values[head];
        head++;
        return result;
    }

    @Override
    public String toString() {
        return "QueueBasedArray{" +
                "values=" + Arrays.toString(values) +
                ", capacity=" + capacity +
                ", head=" + head +
                ", tail=" + tail +
                '}';
    }
}
複製代碼

測試代碼:ide

QueueBasedArray qba = new QueueBasedArray(10);
    System.out.println(qba);

    for (int i = 0; i < 10; i++) {
        qba.enqueue("" + i + i + i);
    }
    System.out.println(qba);

    for (int i = 0; i < 10; i++) {
        qba.dequeue();
        System.out.println(qba);
    }

    for (int i = 11; i < 20; i++) {
        qba.enqueue("" + i + i + i);
    }
    System.out.println(qba);
複製代碼

輸出結果:符合預期測試

QueueBasedArray{values=[null, null, null, null, null, null, null, null, null, null], capacity=10, head=0, tail=0}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=0, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=1, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=2, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=3, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=4, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=5, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=6, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=7, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=8, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=9, tail=10}
QueueBasedArray{values=[000, 111, 222, 333, 444, 555, 666, 777, 888, 999], capacity=10, head=10, tail=10}
QueueBasedArray{values=[111111, 121212, 131313, 141414, 151515, 161616, 171717, 181818, 191919, 999], capacity=10, head=0, tail=9}
複製代碼

鏈式隊列

代碼以下:ui

public class QueueBasedLinkedList implements QueueInterface {
    private Node head;
    private Node tail;

    /**
     * 入隊
     *
     * @param value
     * @return
     */
    @Override
    public Boolean enqueue(String value) {
        Node newNode = new Node(value, null);

        // tail爲null,表示隊列中沒有數據
        if (null == tail) {
            head = newNode;
            tail = newNode;
        } else {
            tail.next = newNode;
            tail = newNode;
        }

        return true;
    }

    /**
     * 出隊
     *
     * @return
     */
    @Override
    public String dequeue() {
        // head == null,表示隊列爲空。
        if (null == head) {
            return null;
        }

        // 獲取數據
        String value = head.getItem();
        // 移除頭結點,讓head指向下一個結點。
        head = head.next;
        // 若是此時的頭結點指向null,說明隊列已空,須要將tail指向null.
        if (null == head) {
            tail = null;
        }

        return value;
    }

    @Override
    public String toString() {
        return "QueueBasedLinkedList{" +
                "head=" + head +
                ", tail=" + tail +
                '}';
    }

    private static class Node {
        String item;
        private Node next;

        public Node(String item, Node next) {
            this.item = item;
            this.next = next;
        }

        public String getItem() {
            return item;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "item='" + item + '\'' + ", next=" + next + '}'; } } } 複製代碼

測試代碼:this

// 空隊列
    QueueBasedLinkedList qbll = new QueueBasedLinkedList();
    System.out.println("空隊列 " + qbll);
    System.out.println();

    // 入隊一個數據
    System.out.println("數據入隊是否成功:" + qbll.enqueue("0000"));
    System.out.println("入隊一個數據後:" + qbll);
    System.out.println();

    // 出隊一個數據
    System.out.println("出隊的數據是:" + qbll.dequeue());
    System.out.println("出隊一個數據後:" + qbll);
    System.out.println();

    // 異常測試:從空隊列中出隊,看結果
    System.out.println("出隊的數據是1:" + qbll.dequeue());
    System.out.println("出隊一個數據後1:" + qbll);
    System.out.println();

    // 入隊十條數據
    for (int i = 0; i < 10; i++) {
        System.out.println("數據入隊是否成功:" + qbll.enqueue("" + i + i + i));
        System.out.println(qbll);
    }
複製代碼

輸出結果:符合預期spa

空隊列 QueueBasedLinkedList{head=null, tail=null}

數據入隊是否成功:true
入隊一個數據後:QueueBasedLinkedList{head=Node{item='0000', next=null}, tail=Node{item='0000', next=null}}

出隊的數據是:0000
出隊一個數據後:QueueBasedLinkedList{head=null, tail=null}

出隊的數據是1:null
出隊一個數據後1:QueueBasedLinkedList{head=null, tail=null}

數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=null}, tail=Node{item='000', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=null}}, tail=Node{item='111', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=null}}}, tail=Node{item='222', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=Node{item='333', next=null}}}}, tail=Node{item='333', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=Node{item='333', next=Node{item='444', next=null}}}}}, tail=Node{item='444', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=Node{item='333', next=Node{item='444', next=Node{item='555', next=null}}}}}}, tail=Node{item='555', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=Node{item='333', next=Node{item='444', next=Node{item='555', next=Node{item='666', next=null}}}}}}}, tail=Node{item='666', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=Node{item='333', next=Node{item='444', next=Node{item='555', next=Node{item='666', next=Node{item='777', next=null}}}}}}}}, tail=Node{item='777', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=Node{item='333', next=Node{item='444', next=Node{item='555', next=Node{item='666', next=Node{item='777', next=Node{item='888', next=null}}}}}}}}}, tail=Node{item='888', next=null}}
數據入隊是否成功:true
QueueBasedLinkedList{head=Node{item='000', next=Node{item='111', next=Node{item='222', next=Node{item='333', next=Node{item='444', next=Node{item='555', next=Node{item='666', next=Node{item='777', next=Node{item='888', next=Node{item='999', next=null}}}}}}}}}}, tail=Node{item='999', next=null}}
複製代碼

完整代碼請查看

項目中搜索SingleLinkedList便可。

github傳送門 github.com/tinyvampire…

gitee傳送門 gitee.com/tinytongton…

參考: 隊列:隊列在線程池等有限資源池中的應用

相關文章
相關標籤/搜索