數據結構--隊列(java)

隊列是一種先進先出的數據結構

隊列上的插入操作叫入隊列,刪除操作叫出隊列

隊列有對頭,和隊尾

就想超市結賬排隊一樣,顧客總是排到隊列的尾部(隊尾),也就是說在隊列的尾部入隊列,隊列的頭部出隊列。

如何在java中實現隊列有兩種選擇,一種是通過數組實現,一種是通過鏈表實現

數組實現的隊列:

//隊列接口
interface Queue<T>{
    boolean enQueue(T k);
    T deQueue();

    boolean isEmpty();

    void clear();

    int length();
}

//順序隊列
class ArrayLinerQueue<T> implements Queue<T>{

    private int size=0;
    private int head=0;
    private int tail=0;
    private Object[] data = new Object[4];

    @Override
    public boolean enQueue(T k) {
        // 判斷是否需要進行數組擴容
        if (tail >= data.length) {
            resize();
        }
        System.out.println("enQueue: " + k);
        data[tail++] = k;
        size++;
        return true;
    }
    /**
     * 數組擴容
     */
    private void resize() {
        System.out.println("數組空間不夠,擴容");
        Object[] temp = new Object[data.length * 2];
        for (int i = head; i < tail; i++) {
            temp[i] = data[i];
            data[i] = 0;
        }
        data = temp;
    }
    @Override
    public T deQueue() {
        if (size == 0) {
            return null;
        }
        System.out.println("deQueue:"+(T)data[head]);
        size--;
        return  (T)data[head++];
    }

    @Override
    public boolean isEmpty() {
        return size==0;
    }

    @Override
    public void clear() {
        // 將數組中的數據置爲null, 方便GC進行回收
        for (int i = 0; i < size; i++) {
            data[size] = null;
        }
        size = 0;
        head=0;
        tail=0;
    }

    @Override
    public int length() {
        return size;
    }

    @Override
    public String toString() {
        return "ArrayQueue{" +
                "size=" + size +
                ", head=" + head +
                ", tail=" + tail +
                ", data=" + Arrays.toString(data) +
                '}';
    }
}

//順序循環隊列
class ArrayCycleQueue<T> implements Queue<T>{

    private int size=0;
    private int head=0;
    private int tail=0;
    private Object[] data = new Object[4];

    @Override
    public boolean enQueue(T k) {
        // 判斷是否需要進行數組擴容
        if (head==tail && head!=0) {
            resize();
        }
        if (tail>=data.length && head>0){
            tail=0;
        }
        System.out.println("enQueue: " + k);
        data[tail++] = k;
        size++;
        return true;
    }
    /**
     * 數組擴容
     */
    private void resize() {
        System.out.println("數組空間不夠,擴容");
        Object[] temp = new Object[data.length * 2];
        for (int i = head+data.length; i < temp.length; i++,head++) {
            temp[i] = data[head];
        }
        for (int i = 0; i < tail; i++) {
            temp[i] = data[i];
        }

        data = temp;
    }
    @Override
    public T deQueue() {
        if (size == 0) {
            return null;
        }
        System.out.println("deQueue:"+(T)data[head]);
        size--;
        return  (T)data[head++];
    }

    @Override
    public boolean isEmpty() {
        return size==0;
    }

    @Override
    public void clear() {
        // 將數組中的數據置爲null, 方便GC進行回收
        for (int i = 0; i < size; i++) {
            data[size] = null;
        }
        size = 0;
        head=0;
        tail=0;
    }

    @Override
    public int length() {
        return size;
    }

    @Override
    public String toString() {
        return "ArrayQueue{" +
                "size=" + size +
                ", head=" + head +
                ", tail=" + tail +
                ", data=" + Arrays.toString(data) +
                '}';
    }
}

鏈表實現的隊列


//鏈表實現隊列
class LinkedListQueue<T> implements Queue<T>{

    private int size=0;
    private QueueNode head=null;
    private QueueNode tail=null;

    @Override
    public boolean enQueue(T k) {

        System.out.println("enQueue: " + k);
        QueueNode queueNode = new QueueNode();
        queueNode.setData(k);

        if (tail==null){
            tail=queueNode;
            head=tail;
        }else {
            tail.setNext(queueNode);
            tail=queueNode;
        }
        size++;
        return true;
    }

    @Override
    public T deQueue() {
        if (size == 0) {
            return null;
        }
        T tempdata = head.getData();
        head=head.getNext();
        System.out.println("deQueue:"+tempdata);
        size--;
        return  tempdata;
    }

    @Override
    public boolean isEmpty() {
        return size==0;
    }

    @Override
    public void clear() {
        size = 0;
        head=null;
        tail=null;
    }

    @Override
    public int length() {
        return size;
    }

    @Override
    public String toString() {

        StringBuilder sb = new StringBuilder();

        QueueNode temp = head;
        while (temp!=null){
            sb.append(temp.getData()+" ");
            temp=temp.getNext();
        }
        return "LinkedListQueue{" +
                "size=" + size +
                ", head=" + head.getData() +
                ", tail=" + tail.getData() +
                ", queue="+sb.toString()+
                '}';
    }

    private class QueueNode{
        private T data;
        private QueueNode next;

        public T getData() {
            return data;
        }

        public void setData(T data) {
            this.data = data;
        }

        public QueueNode getNext() {
            return next;
        }

        public void setNext(QueueNode next) {
            this.next = next;
        }
    }

}

測試

package com.zq.datastruct.linkedlist;

import java.util.Arrays;

/**
 * Created by zhengshouzi on 2015/11/16.
 */
public class QueueTest {
    public static void main(String[] args) {
        Queue<Integer> queue =null;

        System.out.println("------------------------arrayLinerQueue-------------------------------------");

        queue=new ArrayLinerQueue();

        queue.enQueue(32);
        queue.enQueue(43);
        queue.deQueue();
        queue.enQueue(98);

        System.out.println(queue.toString());
        queue.enQueue(444);
        System.out.println(queue.toString());
        queue.enQueue(444);

        System.out.println(queue.toString());

        System.out.println("------------------------arrayCycleQueue-------------------------------------");

       queue = new ArrayCycleQueue<>();

        queue.enQueue(32);
        queue.enQueue(43);
        queue.deQueue();
        queue.enQueue(98);

        System.out.println(queue.toString());
        queue.enQueue(444);
        System.out.println(queue.toString());
        queue.enQueue(567);
        queue.enQueue(1200);

        System.out.println(queue.toString());



        System.out.println("------------------------linkedListQueue-------------------------------------");

       queue = new LinkedListQueue();

        queue.enQueue(32);
        queue.enQueue(43);
        queue.deQueue();
        queue.enQueue(98);

        System.out.println(queue.toString());
        queue.enQueue(444);

        System.out.println(queue.toString());
        queue.enQueue(567);
        queue.enQueue(1200);

        System.out.println(queue.toString());

    }
}

這裏寫圖片描述



隊列應用:

當多個任務分配給打印機時,爲了防止衝突,創建一個隊列,把任務入隊,按先入先出的原則處理任務。
當多個用戶要訪問遠程服務端的文件時,也用到隊列,滿足先來先服務的原則。
現如今衆多的消息中間件的實現就是採用隊列的思想。
……
有一個數學的分支,叫隊列理論(queuing theory )。用來計算 預測用戶在隊中的等待時間,隊的長度等等問題。
答案取決於用戶到達隊列的頻率,用戶的任務的處理時間。如果比較簡單的情況,可以單單用分析解決。一個簡單的例子就是,
一部電話,一個接線員。當一個電話打進來,如果接線員很忙,就電話放到等待線路後。接線員從隊頭開始應答。
凡事一切需要按照順序來處理的數據,都可以用隊列來實現,如果順序帶有優先級,可以用優先隊列

隊列和棧的說明:

隊列比較適合於用鏈表實現:因爲隊列的操作在隊列的兩端進行,使用數組不方便

棧比較適合於用數組實現:而棧的操作始終在棧頂進行,始終在數組頂部操作就好了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章