資料結構之 佇列

2021-10-08 15:32:15 字數 4351 閱讀 2331

由於插入和刪除分別在隊尾和隊頭進行,最先入隊的總是最先出隊。因此佇列的特點是「先進先出」。佇列的基本操作有建立佇列、判斷佇列是否為空、入隊和出隊。佇列和棧一樣,不支援對指定位置的插入和刪除。

宣告佇列介面queue< t >如下

package queue;

public

inte***ce

queue

實現queue< t >佇列介面的類有順序迴圈佇列、鏈式迴圈佇列和優先佇列。

佇列也有順序和鏈式兩種儲存結構,分別稱為順序佇列和鏈式佇列。

1.順序佇列

(1)使用順序表,出隊效率低

如果使用乙個順序表作為佇列的成員變數,入隊操作執行順序表尾插入,時間複雜度為0(1);出隊操作執行順序表頭刪除,時間複雜度都為o(n),效率較低。希望出隊操作效率也是o(1),因此,不使用乙個順序表作為佇列的成員變數。

(2)使用陣列,存在假溢位

順序佇列使用陣列儲存資料元素,用front、rear記住佇列頭、尾元素下標,入隊、出隊時,改變front、rear取值,則不需要移動元素。我們舉個例子來分析一下:

假設陣列長度為5.

(a)佇列初始空狀態,令front和rear都為-1;

(b)10入隊,此時front=rear=0;

(c)20和30入隊,此時front=0,rear=2;

(d)10和20出隊,此時front=rear=2;

(e)40和50入隊,front=2,rear=4;

(f)60想要入隊,front=2,rear=length=5,隊尾下標越界,假溢位。

思路可描述如下:

(1)當佇列空時,設定隊頭、隊尾下標front和rear=-1.

(2)當第乙個元素入隊,front=rear=0,同時改變了兩個下標。

(3)入隊操作,元素存入rear位置,rear++。

(4)出隊操作,返回front隊頭元素,front++。

(5)當入隊的元素個數超過陣列容量,rear下標越界,資料溢位,此時,由於之前已有若干元素出隊,陣列前部已多出許多儲存單元,所以這種溢位不是因為儲存空間不夠,稱為假溢位。

順序佇列存在兩個缺點:假溢位以及一次入隊/出隊操作需要同時改變兩個下標。為解決這個問題,我們可以把順序佇列設計成迴圈結構。

2.順序迴圈佇列

順序迴圈佇列就是邏輯上首尾相連的迴圈結構,這樣可以連續使用儲存單元。

設front是隊頭元素下標,rear是下乙個入隊元素下標

(1)設定初始空隊列為font=rear=0,約定佇列空的條件就是front=rear。

(2)入隊操作改變rear,出隊操作改變front,變化規律如下,其中length表示陣列容量。

設length=5:

(a)初始化空佇列,令front=rear=0;

(b)10和20入隊。front=0,rear=2;

(c)10和20出隊。front=rear=2;

(d)30、40、50、60入隊。此時front=2,rear=1,佇列滿front==(rear+1)%length

(e)擴充容量後,front=0,rear=4.

(3)約定佇列滿條件是front==(rear+1)%length,此時佇列中依然有乙個空的位置,因為如果不保留乙個位置,佇列滿的條件也是front==rear,與佇列空條件相同。

(4)當佇列滿時再入隊,將陣列容量擴充一倍,按照佇列元素次序複製陣列元素。

3.順序迴圈佇列類

宣告順序迴圈佇列類seqqueue< t >如下,實現佇列介面。

package queue;

public

class

seqqueue

implements

queue

this

.element=

newobject

[length]

;this

.front=

this

.rear=0;

//設定空佇列

}public

seqqueue()

@override

public

boolean

isempty()

@override

public

boolean

add(t x)if(

this

.front==

(this

.rear+1)

%this

.element.length)

this

.front=0;

this

.rear=j;

}this

.element[

this

.rear]

=x;this

.rear=

(this

.rear+1)

%this

.element.length;

return

true;}

@override

public t peek()

@override

public t pool()

t temp=

(t)this

.element[

this

.front]

;this

.front=

(this

.front+1)

%this

.element.length;

return temp;

}}

(1)使用單鏈表,入隊效率低

1.使用乙個單鏈表作為佇列的成員變數,入隊操作執行單鏈表尾插入,時間複雜度為o(n),效率較低;出隊操作執行單鏈表頭刪除,時間複雜度為o(1)。因此,不能用乙個單鏈表作為佇列的成員變數,因為入隊操作達不到o(1)。

2.使用乙個迴圈雙鏈表作為佇列的成員變數,入隊操作執行迴圈雙鏈表尾插入,出隊操作執行迴圈雙鏈表頭刪除,時間複雜度都為o(1),但占用較多的空間。

(2)單鏈表設計,增加尾指標

以下為單鏈表(不帶頭結點)實現鏈式佇列的過程。設front和rear分別指向隊頭和隊尾結點,增加乙個尾指標,即可使入隊和出隊操作的空間複雜度都是o(1).

1.設定初始空佇列,front=rear=null,佇列空條件是front == null&&rear==null。

2.入隊操作,將x結點鏈在rear之後,並使rear指向x結點成為新的隊尾。

3.出隊操作,當佇列不空時,取得隊頭結點元素,刪除隊頭結點,並使front指向後繼結點。

4.當第乙個元素入隊或最後乙個元素出隊時,同時改變front和rear。

宣告鏈式佇列類linkedqueue如下,實現佇列介面,其中成員變數front和rear分別指向佇列頭結點和尾節點,資料型別都是單鏈表結點類node。

package queue;

import datastructure.node;

public

final

class

linkedqueue

implements

queue

@override

public

boolean

isempty()

@override

public

boolean

add(t x)

node

q=new

node

(x,null);if

(this

.front==null)

else

this

.rear=q;

return

true;}

@override

public t peek()

@override

public t pool()

t x=

this

.front.data;

//取得隊頭元素

this

.front=

this

.front.next;

//刪除隊頭結點if(

this

.front==null)

return x;

}}

結點node類:

package datastructure;

public

class

node

public

node()

public string tostring()

}

資料結構之佇列

八 佇列 鏈式佇列 鍊錶實現 隊尾 rear 隊首 front 靜態佇列 陣列實現 必須是迴圈佇列 需要幾個引數來確定,各引數含義 1 佇列初始化 front和rear值都是0 2 佇列非空 front代表佇列第乙個元素 rear代表佇列最後乙個元素的 下乙個元素 3 佇列空 front和rear相...

資料結構之佇列

與棧相反,佇列是一種先進先出的線性表,它只允許在表的一端進行,而在另一端刪除元 素。在佇列中,允許插入的一端叫做隊尾,允許刪除的一端則稱為隊頭。1 鏈佇列 佇列的鏈式表示和實現 用鍊錶表示的佇列簡稱為鏈佇列,乙個鏈佇列顯然需要兩個分別指示對頭和隊尾的指標 分別稱為頭指 針和尾指標 才能唯一確定。這裡...

資料結構之佇列

一 佇列的介紹 佇列 queue 是一種線性儲存結構。它有以下幾個特點 1 佇列中資料是按照 先進先出 fifo,first in first out 方式進出佇列的。2 佇列只允許在 隊首 進行刪除操作,而在 隊尾 進行插入操作。佇列通常包括的兩種操作 入佇列 和 出佇列。1.佇列的示意圖 佇列中...