資料結構之佇列 Queue

2022-06-10 11:12:07 字數 3985 閱讀 5446

之前總結過棧相關的知識,佇列可以模擬棧來看。棧只能在一端進行操作(棧頂),新增元素或者刪除等都只能在棧頂;而佇列有兩端可以操作,在一端新增元素,在另一端刪除元素

我們把新增元素的一端稱為隊尾;刪除元素的一端稱為隊首。

比如生活中的排隊:城市中基本**都有,這就是乙個佇列。在隊伍最前面就是隊首,也是最先完成離開隊伍的。新來的只能在隊尾加入。

佇列的特點:用鍊錶、陣列都比較容易實現佇列。

鍊錶實現:比較簡單,在鍊錶首部刪除,鍊錶尾部插入即可。

鍊錶沒有長度限制,不會造成溢位,而且插入刪除也很簡單,是很適合的實現方式。

陣列實現:普通陣列方式,有著明顯的缺陷,長度固定、出隊時剩下所有元素都要向前挪動一位,這種出隊方式時間複雜度就是o(n)了。在此基礎上進行一些處理,形成乙個環,成為乙個迴圈佇列

所以下面主要介紹的就是兩種佇列實現,用鍊錶實現的佇列 和 用陣列實現的迴圈佇列

佇列主要兩個操作,入隊和出隊。

入隊(enqueue):即在隊尾插入新元素。

出隊(dequeue):即在隊首刪除乙個元素。

如果自己實現,可以新增更多公共操作,如隊長、是否隊空或隊滿、查詢等等。

下面實現中,為了更直觀的顯示出隊、入隊操作,都新增了乙個displayqueue()的方法。

單鏈表佇列實現很簡單,鍊錶首部即隊首,鍊錶尾部即隊尾,定義兩個引用分別指向隊首和隊尾,出隊、入隊直接刪除和插入即可。時間複雜度為o(1)。

優勢,沒有額外的操作,沒有長度的限制 不需擔心溢位。

示意圖大致如下:

具體**如下(可結合注釋,應該比較清晰):

public class queuelinkedlist

queuelinkedlist.displayqueue();

queuelinkedlist.dequeue();

queuelinkedlist.displayqueue();

queuelinkedlist.dequeue();

queuelinkedlist.displayqueue(); }

//定義隊首引用,指向鍊錶首部

private queuenodefront;

//定義隊尾引用,指向鍊錶尾部

private queuenoderear;

//節點定義

static class queuenode }

//初始化,空的佇列。

public queuelinkedlist()

//入隊,鍊錶尾部插入

public void enqueue(e value)

this.rear.next = newnode;

this.rear = newnode; }

//出隊,鍊錶首部刪除

public e dequeue()

//列印佇列所有元素,以及隊首、隊尾資訊

public void displayqueue()

system.out.println("front:" + this.front.data +"

queuenodetmpnode = this.front;

while (tmpnode != null)

system.out.println();

system.out.println();

}}

實驗結果為:

front:null

this is an empty queue!

front:1

1front:2

2front:3

3

若用普通陣列實現佇列,就會發現每次刪除隊首時所有元素都需要向前移動一位,這樣實現肯定是不合適的。

於是,在上述基礎上做一些處理,便形成了迴圈佇列:將陣列佇列看出乙個首尾相連的環形。用front和rear表示隊首和隊尾相關元素的下標(不一定是front是隊首下標,rear是隊尾下表),這樣就能很容易確定佇列的元素是哪些了。出隊、入隊改變這兩個值即可而不需要移動陣列中元素了。

下面實現用變數front和rear標識隊首、隊尾的下標,入隊和出隊的方式基本一致:陣列大小為capacity,即front=(font+1)%capacity 或 rear=(rear+1)%capacity。

也可以用front標識隊首,rear標識隊尾的下乙個位置,只是不同的標識含義, 初始化 和 隊列為空 及 隊列為滿 的判斷和處理需要注意,是不同的。(rear標識隊尾下乙個位置時,初始化front=rear=0,空即front==rear。而rear標識隊尾即下面的實現,可以具體看下)

大致示意圖如下(front和rear標識隊首、隊尾的下標):

實現**(可結合注釋檢視):

注:實現中的判空與判滿 使用了另乙個變數queuecount表示佇列元素個數,便於返回佇列大小。也可以使用front和rear之間關係進行判斷

public class queuecirclearray 

queuecirclearray.displayqueue();

queuecirclearray.dequeue();

queuecirclearray.dequeue();

queuecirclearray.displayqueue();

queuecirclearray.enqueue(integer.valueof(10));

queuecirclearray.enqueue(integer.valueof(20));

queuecirclearray.displayqueue(); }

//陣列及大小

private object array;

private int capacity;

//隊首 隊尾對應陣列中的下標

private int front, rear;

//佇列的大小

private int queuecount;

public queuecirclearray()

public queuecirclearray(int capacity)

public boolean isfull()

public boolean isempty()

public void enqueue(object value)

public object dequeue()

public void displayqueue()

int tmp = this.front;

system.out.println("front:["+ this.front + "]" + this.array[this.front]

+"while(tmp != this.rear)

if (tmp == this.rear)

system.out.println(this.array[tmp]);

system.out.println();

}}

實驗結果:

front:null

this is an empty queue!

front:[0]1

1front:[2]3

3front:[2]3

3

資料結構之佇列(Queue)

佇列,顧名思義,也就是一條隊伍,進入隊伍的時候,只能從隊尾排隊,離開隊伍的時候,只能從隊首離開。佇列也有陣列實現和鏈式實現。用一般陣列實現佇列的時候,入隊,則在隊尾插入乙個元素,出隊,則將隊首的元素出隊。那麼,由於陣列的長度是固定的,入隊只能從隊尾入隊,因此經常性的出隊會使得隊首越來越靠近隊尾,隊首...

python資料結構之佇列(queue)

佇列是一種特殊的線性表,先進先出,只允許在前端進行刪除,在後端進行插入操作,它的操作方式與堆疊類似,區別在於佇列只允許在後端插入資料。在python中有相應的類 import queue q queue.queue for i in range 4 q.put i 將乙個值放入佇列中 while n...

C 資料結構之Queue(佇列)

queue,佇列,和我們日常生活中的佇列是同樣的規則,先進先出 從尾入,從首出。有外加的一些操作如 full 佇列是否已滿 serve and retrieve 檢視隊首元素同時去除 等等。在eclipse執行通過 h標頭檔案 queue.h created on 2015年8月22日 author...