資料結構之迴圈佇列(Java實現)

2021-08-21 11:20:43 字數 3745 閱讀 6245

理論參考其他文章!!!

我們假設乙個佇列有n個元素,則順序儲存的佇列需建立乙個大於n的陣列,並把佇列的所有元素儲存在陣列的前n個單元,陣列下標為0的一端即是隊頭。所謂的入佇列操作,其實就是在隊尾追加乙個元素,不需要移動任何元素,因此時間複雜度為0(1)。

與棧不同的是,佇列元素的出列是在隊頭,即下標為0的位置,那也就意味著,佇列中的所有元素都得向前移動,以保證佇列的隊頭(也就是下標為0的位置)不為空,此時的時間複雜度為0(n)。

可有時想想,為什麼出佇列時一定要全部移動呢,如果不去限制佇列的元素必須儲存在陣列的前n個單元這一條件,出隊的效能就會大大增加。也就是說,隊頭不需要一定在下標為0的位置,比如也可以是a[1]等。

為了避免當只有乙個元素時,隊頭和隊尾重合使處理變得麻煩,所以引入兩個指標,front指標指向隊頭元素,rear指標指向隊尾元素的下乙個位置,這樣當front等於rear時,此佇列不是還剩乙個元素,而是空佇列。

假設是長度為5的陣列,初始狀態,空佇列如所示,front與 rear指標均指向下標為0的位置。然後入隊a1、a2、a3、a4, front指標依然指向下標為0位置,而rear指標指向下標為4的位置。

出隊a1、a2,則front指標指向下標為2的位置,rear不變,如下圖所示,再入隊a5,此時front指標不變,rear指標移動到陣列之外。嗯?陣列之外,那將是**?

問題還不止於此。假設這個佇列的總個數不超過5個,但目前如果接著入隊的話,因陣列末尾元素已經占用,再向後加,就會產生陣列越界的錯誤,可實際上,我們的佇列在下標為0和1的地方還是空閒的。我們把這種現象叫做「假溢位」。

為了解決這個問題,我們後面會引入迴圈佇列的概念。

前面講到了佇列的「假溢位」,解決假溢位的辦法就是後面滿了,就再從頭開始,也就是頭尾相接的迴圈。我們把佇列的這種頭尾相接的順序儲存結構稱為迴圈佇列。

比如昨天的例子,rear可以改為指向下標為0的位置,這樣就不會造成指標指向不明的問題了。

但是如果繼續進行入隊操作的話,比如繼續插入a6、a7,則rear指標就與front指標重合,同時指向下標為2的位置。

我們來討論第二種方法,由於rear可能比front大,也可能比front小,所以儘管它們只相差乙個位置時就是滿的情況,但也可能是相差整整一圈。所以若佇列的最大尺寸為queuesize,那麼佇列滿的條件是(rear+1) %queuesize == front (取模「%的目的就是為了整合rear與front大小為乙個問題)。

比如上面這個例子, queuesize = 5,當 front=0,而 rear=4, (4+1) %5 = 0,所以此時佇列滿。再比如,front = 2而rear =1。(1 + 1) %5 = 2,所以此時 佇列也是滿的。而對於下圖, front = 2而rear= 0, (0+1) %5 = 1,1!=2,所以此時佇列並沒有滿。

另外,當rear > front時,此時佇列的長度為rear—front。但當rear < front時,佇列長度分為兩段,一段是queuesize-front,另一段是0 + rear,加在一起,佇列長度為rear-front + queuesize,因此通用的計算佇列長度公式為:

(rear—front + queuesize) % queuesize

有了這些講解,現在實現迴圈佇列的**就不難了。具體的例子程式可以參照前面說的順序佇列。

package com.perkinl.queue;

public inte***ce queue

package com.perkinl.queue;

public class array

// 無引數的建構函式,預設陣列的容量capacity=10

public

array()

// 獲取陣列的容量

public int

getcapacity()

// 獲取陣列中的元素個數

public int

getsize()

// 返回陣列是否為空

public boolean

isempty()

// 在index索引的位置插入乙個新元素e

public void

add(int index,

e e)

// 向所有元素後新增乙個新元素

public void

addlast(e e)

// 在所有元素前新增乙個新元素

public void

addfirst(e e)

// 獲取index索引位置的元素

public

e get(int index)

public

e getlast()

public

e getfirst()

// 修改index索引位置的元素為e

public void

set(int index,

e e)

// 查詢陣列中是否有元素e

public boolean

contains(e e)

return false;

} // 查詢陣列中元素e所在的索引,如果不存在元素e,則返回-1

public int

find(e e)

return -1;}

// 從陣列中刪除index位置的元素, 返回刪除的元素

public

e remove(int index)

// 從陣列中刪除第乙個元素, 返回刪除的元素

public

e removefirst()

// 從陣列中刪除最後乙個元素, 返回刪除的元素

public

e removelast()

// 從陣列中刪除元素e

public void

removeelement(e e)

@override

public string tostring()

return res.tostring();

} // 將陣列空間的容量變成newcapacity大小

private void

resize(int newcapacity)

}

package com.perkinl.queue;

/*** 迴圈佇列

*@param

<

e>

*/public class loopqueue implements queue

public

loopqueue()

public int

getcapacity()

@override

public boolean

isempty()

@override

public int

getsize()

@override

public void

enqueue(e e)

@override

public

e dequeue()

@override

public

e getfront()

private void

resize(int newcapacity)

@override

public string tostring()

return res.tostring();

} public static void

main(string args)}}

}

JAVA資料結構之迴圈佇列的實現

1 迴圈佇列circlequeue類的實現 如下所示 public class circlequeue 入隊 boolean ret array null capacity 0 if ret return ret 出隊 public object retrieve return data 獲取佇列中...

資料結構之迴圈佇列

資料結構之佇列 迴圈佇列 ide vs2010 佇列操作 初始化 入隊 插入隊尾 出隊 即取隊頭 判斷佇列是否非空 滿 include using namespace std define max len 100 定義節點型別 typedef struct queue queue 初始化 void ...

資料結構之迴圈佇列

4.10 佇列的定義 佇列定義 一種先進先出的線性表。允許插入的一端稱為隊尾,允許刪除的一端稱為隊頭。隊頭 隊尾 出佇列 a1 a2 a3 a4 an 入佇列 佇列有類似線性表的各種操作,不同的就是插入資料只能在隊尾進行,刪除資料只能在隊頭進行。線性表有線性儲存和鏈式儲存。棧是線性表,有這兩種儲存方...