1. 程式人生 > >java佇列的陣列實現

java佇列的陣列實現

原始碼的github地址,可以下載到本地執行
佇列介面:

package Interface;

/**
 * 佇列介面
 * <p>
 * 佇列是一種先進先出的線性表
 * 只能在表的一端進行插入,另一段進行刪除
 * 允許插入的一端叫隊尾,允許刪除的一端叫隊頭()
 *
 *
 * ps:還存在一種 雙端佇列 即隊頭和隊尾都可以進行插入和刪除的操作,隊頭和隊尾在這裡叫端點
 * 以及輸入受限的雙端佇列(一端輸入和刪除,另一端只能刪除)
 * 輸出受限的雙端佇列(一端輸入和刪除,另一端只能輸入)
 * 但是雙端佇列應用不廣泛 不在此做討論
 */
public interface IQueue<T> {

    /**
     * 初始化佇列 構造一個空佇列
     */
    IQueue InitQueue();

    /**
     * 銷燬佇列
     */
    IQueue DestroyQueue();

    /**
     * 清空佇列
     */
    IQueue ClearQueue();

    /**
     * 佇列判空
     */
    Boolean isEmpty();

    /**
     * 返回佇列長度
     */
    Integer QueueLength();

    /**
     * 返回佇列頭元素
     */
    T GetHead();

    /**
     * 插入隊尾元素
     */
    Boolean EnQueue(T e);

    /**
     * 刪除隊頭元素  即出隊
     */
    T DeQueue();

}
package impl;

import Interface.IQueue;

/**
 * 陣列型佇列
 * <p>
 * 同樣需要一個頭指標,一個尾指標  當頭指標=尾指標=0時候為空
 * 需要實現分配一個固定大小的陣列
 * 正常情況下下,尾指標永遠指向隊尾元素的下一個位置,比如說隊尾元素在0 尾指標則在1
 * <p>
 * 注意!:陣列型佇列有很大的劣勢,容易造成儲存空間浪費,而且不易擴容。
 * 比如說,最大空間為6的陣列佇列, 進去了6個了元素,然後從隊頭出去了5個元素,此時,仍然不能插入新的元素
 * 因為隊尾指標仍然指向第6個元素,其仍然佔據了最後一個位置,而隊頭是不允許插入的。這樣造成前面5個位置浪費。
 * <p>
 * 解決方法:1.元素移動位置,出隊一個 後面的元素往前挪。   缺點:每次出隊都需要移動位置 很麻煩 效率也低
 * 2.動態擴容,  缺點:浪費了前面的空間
 * 3.最佳解決方案:構造環形佇列
 */
public class ArrayQueue<T> implements IQueue {
    private Integer size;
    private Integer header;
    private Integer tail;
    private final Integer length = 6;
    private Object[] arr;

    public IQueue InitQueue() {
        arr = new Object[length];
        tail = header = size = 0;
        return this;
    }

    public IQueue DestroyQueue() {
        arr = null;
        tail = header = size = 0;
        return this;
    }

    public IQueue ClearQueue() {
        tail = header = size = 0;
        for (int i = 0; i < arr.length; i++) {
            arr[i] = null;
        }
        return this;
    }

    public Boolean isEmpty() {
        if (tail == header) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    public Integer QueueLength() {
        return size;
    }

    public Object GetHead() {
        return arr[header];
    }

    public Boolean EnQueue(Object e) {
        if (size >= length) {
            return Boolean.FALSE;
        }

        if (header == tail) {//先判斷是不是空的 如果是 重置頭尾指標  ,不然這個佇列就只能用一次了
            header = 0;
            arr[header] = e;
            tail = 1;
            size++;
            return Boolean.TRUE;
        } else {
            arr[tail] = e;
            tail = tail + 1;
            size++;
            return Boolean.TRUE;
        }


    }

    public Object DeQueue() {
        if (header == tail) {
            return null;
        }
        T e = (T) arr[header];
        header = header + 1;
        size--;
        return e;
    }


    public static void main(String[] args) {
        ArrayQueue<Integer> arrayQueue = new ArrayQueue<Integer>();
        arrayQueue.InitQueue();
        arrayQueue.EnQueue(1);
        arrayQueue.EnQueue(2);
        arrayQueue.EnQueue(3);
        arrayQueue.EnQueue(4);
        arrayQueue.EnQueue(5);
        arrayQueue.EnQueue(6);
        Integer s = arrayQueue.size;
        System.out.println(arrayQueue.GetHead());
        for (Integer integer = 0; integer < s; integer++) {
            System.out.println(arrayQueue.DeQueue());
        }
        System.out.println(arrayQueue.isEmpty());
        arrayQueue.EnQueue(1);
        arrayQueue.EnQueue(2);
        arrayQueue.EnQueue(3);
        arrayQueue.EnQueue(4);
         s = arrayQueue.size;
        for (Integer integer = 0; integer < s; integer++) {
            System.out.println(arrayQueue.DeQueue());
        }
        System.out.println(arrayQueue.isEmpty());
    }
}

輸出結果
1
1
2
3
4
5
6
true
1
2
3
4
true

原始碼的github地址,可以下載到本地執行