Java資料結構-線性表之隊列

來源:互聯網
上載者:User

標籤:資料結構   線性表之隊列   java實現隊列   

隊列(Queue)的定義:只允許在一端進行插入另一端進行刪除操作的線性表。允許插入的一端稱為隊尾(rear) ,允許刪除的一端稱為隊頭(front)。 具有“先進先出”特點。

隊列也是線性表,所以也存在順序結構和鏈式結構。

順序隊列:

對於隊列,入隊操作的解釋為:
(是在隊尾追加一個元素,不需要移動任何元素,因此時間複雜度為0(1)。)

  1. 判斷隊列是否已滿;
  2. 如果沒滿則先給隊尾元素賦值;
  3. 然後將隊尾指標後移一位(對隊尾指標賦值,Q->rear = Q->rear+1 )。

出隊操作解釋為:
(隊列中的所有元素都得向前移動,以保證隊列的隊頭(也就是下標為0的位置)不為空白,此時的時間複雜度為0(n)。)

  1. 判斷隊列是否為空白;
  2. 若不為空白則將對首元素取出用來返回;
  3. 然後將對首指標後移一位(對隊首指標賦值,Q->front = Q->front+1 )。
  4. 隊列是否為空白判斷:隊首指標和隊尾指標進行判斷是否相等。

隊列的實際長度:隊尾指標-對首指標;也可以通過設定一個變數來進行儲存。

下面是我的順序隊列的Java實現:

package com.phn.queue;/** * @author 潘海南 * @Email [email protected] * @TODO 順序隊列 * @date 2015年7月20日 */public class FOArrayQueue<E> {    //預設隊列容量    private static final int DEFUALT_CAPACITY = 100;    //佇列儲存體資料元素的數組    private Object[] data = null;    //隊列的實際大小    private int size;    //隊列的對首索引    private int front;    //隊列的隊尾索引    private int rear;    //隊列的實際容量    private int capacity;    /**     * @TODO 無參建構函式,初始化隊列     */    public FOArrayQueue() {        this(DEFUALT_CAPACITY);    }    /**     * @param initialCapacity 隊列初始化容量     */    public FOArrayQueue(int initialCapacity) {        this.data = new Object[initialCapacity];        this.front = 0;        this.rear = 0;        this.size = 0;        this.capacity = initialCapacity;    }    /**     * @TODO 隊列入隊操作     * @param e 需要入隊的資料元素     * @return true     */    public boolean enQueue(E e){        if(this.isFull()){            throw new RuntimeException("隊列已滿!最大容量="+this.capacity);        }        this.data[this.rear] = e;//      this.rear = (this.rear+1)%(this.capacity);        this.rear = this.rear+1;        this.size++;        return true;    }    /**     * @TODO 隊列的出隊操作     * @return e 位於對首的資料元素     */    public E deQueue(){        if(this.isEmpty()){            throw new RuntimeException("隊列為空白!");        }        E e = (E)this.data[this.front];//      this.front = (this.front+1)%(this.capacity);        this.front = this.front+1;        this.size--;        return e;    }    /**     * @TODO 判斷隊列是否為空白     * @return true空 or false不為空白     */    public boolean isEmpty(){        if(this.front==this.size){            return true;        }        return false;    }    /**     * @TODO 判斷隊列是否已滿     * @return true滿 or false未滿     */    public boolean isFull(){        //這裡不能用size來進行判斷,用size會出現假溢出的情況        if(this.rear==this.capacity-1){            return true;        }        return false;    }    /**     * @TODO 擷取隊列的長度     * @return size     */    public int size(){        return this.size;    }    @Override    public String toString() {        StringBuffer sb = new StringBuffer("[");        if(this.data[this.front]!=null){            sb.append(this.data[this.front]);            for (int i = this.front+1; i < this.rear; i++) {                sb.append(", "+this.data[i]);            }        }        sb.append("]");        return sb.toString();    }}

下面是我的測試代碼:

public static void main(String[] args) {    FOArrayQueue<String> foaq = new FOArrayQueue<String>();    for (int i = 1; i <= 6; i++) {        foaq.enQueue("元素"+i);    }    System.out.println(foaq);    System.out.println(foaq.size());    System.out.println(foaq.deQueue());;    System.out.println(foaq);    System.out.println(foaq.size());}

測試:

??由於隊列的入隊和出隊操作的結果導致隊列容易出現“假溢出”,於是乎出現了迴圈隊列。

迴圈隊列需要注意的地方如下:

  • 執行入隊操作後,隊尾指標的變化:Q->rear = (Q->rear+1)% capacity。
  • 執行出隊操作後,對首指標的變化:Q->front= (Q->front+1)% capacity。
  • 判斷是否為空白的情況:Q->front=Q->rear。
  • 判斷隊列是否為滿的情況,需要放棄隊列一個位置來區分開來隊列是否為空白是否為滿,這樣判斷條件為:Q->front= (Q->rear + 1)% capacity。
  • 隊列實際長度:(隊尾指標-對首指標+數組長度)% 數組長度;或者可以通過設定一個變數來進行儲存;或者都通過Q->front=Q->rear外加一個flag變數進行判斷。

好了,迴圈隊列也就介紹這些。

鏈隊列:
定義:隊列的鏈式儲存結構,其實就是線性表的單鏈表,只不過它只能尾進頭出而已,我們把它簡稱為鏈隊列。
??為了方便操作,將隊頭指標指向鏈隊列的頭結點,而隊尾指標指向終端結點。
??當隊列為空白時,front和rear都指向頭結點。

??正如鏈隊就類似於單鏈表,這裡鏈隊的入隊、出隊、判斷為空白等操作也基本類似,這裡就不描述了,詳情請參考之前的單鏈表。

??其實看了之前的再看這裡其實很容易的,不懂的話還可以參考這個網址:http://www.nowamagic.net/librarys/veda/detail/2357

迴圈隊列和鏈隊列的比較。

  1. 時間上:它們的基本操作都是常數時間O(1),這裡還有點細微的差別(迴圈隊列是事先申請好空間,使用期間不釋放,而對於鏈隊列,每次申請和釋放結點也會存在一些時間開銷,如果入隊出隊頻繁,則兩者還是有細微差異)。
  2. 空間上:迴圈隊列的長度固定,因此有了空間浪費的問題;而鏈隊列不存在這個問題,但是每個節點需要一個指標域,這是需要消耗一定的空間。相對來說,鏈隊列更加靈活。

總結:
??在確定隊列長度最大值的情況,建議使用迴圈隊列;否則請使用鏈隊列。“迴圈隊列”最大優點就是節省空間的和少分配空間,而鏈隊列多了一點點地址儲存開銷。

著作權聲明:本文為博主原創文章,如需轉載請註明出處並附上連結,謝謝。

Java資料結構-線性表之隊列

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.