佇列之順序佇列與迴圈佇列

2021-06-27 00:01:59 字數 3593 閱讀 7349

一、佇列的概念

只能在表的一端進行插入操作,只能在表的另一端進行刪除操作,這種資料結構稱為

佇列。把允許插入的一端叫

隊尾(rear),允許刪除的一端叫

對頭(front)。

二、佇列的分類

佇列本身也是一種線性表,因而和線性表一樣也有順序和鏈式儲存結構兩種儲存方式。

採用順序儲存結構實現的佇列稱為順序佇列;

採用鏈式儲存結構實現的佇列稱為鏈佇列。

三、順序佇列

1、 順序佇列的表示

①順序佇列用乙個向量空間(一般使用一維陣列)來存放當前佇列中的元素。

②由於佇列的隊頭和隊尾的位置是變化的,設定兩個指標front和rear分別指示隊頭元素和隊尾元素在向量空間中的位置,它們的初值在佇列初始化時均應置為0。

2、  順序佇列的基本操作

①入隊時:將新元素插入rear所指的位置,然後將rear加1。

②出隊時:刪去front所指的元素,然後將front加1並返回被刪元素。

注意:①當頭尾指標相等時,隊列為空。

②在非空佇列裡,隊頭指標始終指向隊頭元素,尾指標始終指向隊尾元素的下一位置。

3、 順序佇列中的溢位現象

① "下溢"現象

當隊列為空時,做出隊運算產生的溢位現象。「下溢」是正常現象,常用作程式控制轉移的條件。

② "真上溢"現象

當佇列滿時,做進棧運算產生空間溢位的現象。「真上溢」是一種出錯狀態,應設法避免。

③ "假上溢"現象

由於入隊和出隊操作中,頭尾指標只增加不減小,致使被刪元素的空間永遠無法重新利用。當佇列中實際的元素個數遠遠小於向量空間的規模時,也可能由於尾指標已超越向量空間的上界而不能做入隊操作。該現象稱為"假上溢"現象。

四、迴圈佇列

為充分利用向量空間,克服"假上溢"現象的方法是:將向量空間想象為乙個首尾相接的圓環,並稱這種向量為迴圈向量。儲存在其中的佇列稱為迴圈佇列(circular queue)。

1、 迴圈佇列的基本操作

迴圈佇列中進行出隊、入隊操作時,頭尾指標仍要加1,朝前移動。只不過當頭尾指標指向向量上界(queuesize-1)時,其加1操作的結果是指向向量的下界0。這種迴圈意義下的加1操作可以描述為:

① 方法一:

if(i+1==queuesize) //i表示front或rear

i=0;

else

i++;

② 方法二--利用"模運算"

i=(i+1)%queuesize;

2、 迴圈佇列邊界條件處理

迴圈佇列中,由於入隊時尾指標向前追趕頭指標;出隊時頭指標向前追趕尾指標,造成隊空和隊滿時頭尾指標均相等。因此,無法通過條件front==rear來判別佇列是"空"還是"滿"。 

解決這個問題的方法至少有三種:

① 另設一布林變數以區別佇列的空和滿;

② 少用乙個元素的空間。

約定入隊前,測試尾指標在迴圈意義下加1後是否等於頭指標,若相等則認為隊滿(注意:rear所指的單元始終為空);

③使用乙個計數器記錄佇列中元素的總數(即佇列長度)。

3、程式

#define  

datatype  

int  

#define  

maxsize  

100using namespace std;

typedef  

struct  

_cirqueue 

cirqueue, *pcirqueue;

void  

initqueue(pcirqueue  

pqueue);

bool  

empty(pcirqueue  

pqueue);

bool insertqueue(pcirqueue pqueue, datatype x);

datatype outqueue(pcirqueue pqueue);

datatype  

gethead(pcirqueue  

pqueue);

int  

getlength(pcirqueue  

pqueue);

int _tmain(int argc, _tchar* argv)

insertqueue(&myqueue, 1);

insertqueue(&myqueue, 2);

insertqueue(&myqueue, 3);

insertqueue(&myqueue, 4);

len = getlength(&myqueue);

data = gethead(&myqueue);

while (empty(&myqueue))

return 0; }

//初始化:初始化乙個新的佇列

void  

initqueue(pcirqueue  

pqueue)

//佇列非空判斷:若佇列不為空,則返回true;否則返回false。

bool  

empty(pcirqueue  

pqueue)

else return false; }

//入佇列:在佇列的尾部插入元素x,使元素x成為新的隊尾。若 佇列滿,則返回false;否則,返回true。

bool insertqueue(pcirqueue pqueue, datatype x)

else

return  

false; }

//出佇列:若佇列不為空,則返回對頭元素,並從對頭刪除該元素,對頭指標指向原對頭的後記元素;否則,返回元素null

datatype outqueue(pcirqueue pqueue)

else

} //取對頭元素:若佇列不空,則返回對頭元素;否則,返回空元素null

datatype  

gethead(pcirqueue  

pqueue)

else

} //求佇列長度

int  

getlength(pcirqueue  

pqueue)

return length; }

執行結果:

迴圈佇列 順序佇列

在前兩篇中講述了順序佇列中的隊頭移動與不移動兩種順序佇列,今天討論順序佇列中的迴圈佇列,這種迴圈佇列是用一維陣列實現的。在隊頭移動的情況下,根據元素個數與佇列容量之間的數量關係來解決假溢位問題。從上圖中我們可以理解為什麼這種佇列結構可以解決假溢位問題,但是隨之而來,我們要如何判定迴圈佇列已滿呢?在此...

佇列 順序迴圈佇列

順序佇列 sequence queue 用一片連續的儲存空間來儲存佇列中的資料元素.用一維陣列來存放順序佇列中的資料元素。隊頭位置設在陣列下標為 0 的端,用 front 表示 隊尾位置設在陣列的另一端,用 rear 表示。front 和 rear 隨著插入和刪除而變化。當隊列為空時,front r...

迴圈佇列 順序佇列(C )

佇列 queue 是一種限定訪問位置的線性變。他允許在表的一端插入,在另一端刪除。這個和計算機排程策略中的先來先服務fcfs first come first served 是一樣的。佇列中可以插入的一端為隊尾 rear 允許刪除的一端稱為隊頭 front 佇列也分為兩種,一種是用陣列的儲存表示,一...