C語言小知識 迴圈佇列

2021-10-10 06:51:34 字數 3230 閱讀 2202

三、隊空與隊滿的判斷

總結在演算法中,佇列是個常用的資料型別,具有先進先出的儲存特點。

在python中我們直接呼叫 collections.deque() 就可以構建乙個佇列,那麼在c語言中,該如何簡單地實現乙個佇列呢?

為了節省記憶體空間,c中的佇列要用迴圈佇列實現,它可以迴圈使用位置存放資料。以此實現新入隊的資料,直接覆蓋前面已出隊的無用資料。而不需要考慮如何刪除已出隊的元素,並且使得佇列的長度可以是有限的,只要滿足同時要存放的最多元素個數即可。

迴圈佇列視覺化的圖如下:

先不管這個圈,我們把它拉直的話就是乙個陣列,下標從0開始。它有乙個最大長度的設定,記為max

size

maxsize

maxsiz

e,在初始化時要定義好。在上圖中,max

size

=8maxsize=8

maxsiz

e=8。

但要注意,在我們使用時,這個佇列能同時存放的最大元素個數是 max

size

−1=7

maxsize-1=7

maxsiz

e−1=

7。這是為了能有效判斷隊滿還是隊空,在下面會講到。

除了陣列,我們還設有兩個指標:隊頭指標(front)用於指示隊首元素的位置,隊尾指標(rear)用於指示佇列最後乙個元素的位置。

初始化過程中,就是定義乙個陣列,和兩個指標。當然這個指標不真就是c語言中的指標 ∗

*∗ 資料型別,而是說可以代表陣列中元素位置的「東西」。那麼最簡單的辦法,front 和 rear 直接是陣列下標最好。

我們初始化乙個存放元素是整數的佇列deq

uedeque

dequ

e,並且希望它最多能同時存放max

lenmaxlen

maxlen

個資料:

int deque[maxlen+1]

;//注意初始化時,陣列長度要在資料長度基礎上加1

int front=

0, rear=

0;

注意陣列長度是max

len+

1maxlen+1

maxlen

+1。當想將乙個元素加入佇列時,我們知道要加在隊尾,此時隊尾指標rear指向的陣列位置就是可以新增新元素的位置。因此直接將新元素賦給rear指向的位置,再將rear後移一位。

為了防止rear的值超出陣列長度,我們在後移rear後,對陣列長度取個餘,讓rear迴圈地指回陣列前面的位置。不過,如果我們能很好地設定陣列的長度,保證能一次性放下所有元素,這一步就不是必要的,

int in=5;

//要入隊的元素

deque[rear]

= in;

rear ++

;// 或者:

// deque[rear++] = in;

rear = rear%

(maxlen+1)

;

出隊時從隊首彈出第乙個元素,front指標指向的恰好就是佇列的第乙個元素。因此直接獲取front指向的元素,並將front後移一位。後移front是因為當前值在主觀上已經被彈出,雖然它客觀上還在這個陣列中,但已經可以看作不存在於陣列中了;後面的乙個值才是真正的隊首元素,需要將front指向它。

同樣,對後移後的front取餘。

突然感覺有點哲學意味,嘖…

int out;

//表示彈出的元素

out = deque[front]

;front ++

;// 或者:

// out = deque[front++];

front = front%

(maxlen+1)

;

可以看出rear指標指向隊尾,但它指向的位置永遠是還沒有儲存新元素的(因為我們插入新元素後,馬上將rear後移了);front指向隊首元素,指向的位置是有元素的。

所以,佇列中有效元素的個數(即佇列長度)是

而不是rea

r−fr

ont+

1rear-front+1

rear−f

ront

+1直觀理解,當佇列長度為0時,隊空。因此rea

r==f

ront

rear==front

rear==

fron

t就是隊空條件。

還記得嗎~在定義佇列陣列時,我們給陣列長度刻意多加了個1,這是為了留出來乙個多餘的位置不放元素。這樣,我們才能區分隊滿和隊空的狀態。

隊滿時,rear和front的位置關係是這個亞子的:

直觀來看,轉圈圈方向上,rear在front前乙個位置的時候,佇列就滿了。從數學上嚴謹推導一下,

即( re

ar+1

)%(m

axle

n+1)

==fr

ont(rear+1)\%(maxlen+1)==front

(rear+

1)%(

maxl

en+1

)==f

ront

時,隊滿。

這時,我們思考一下為什麼不能讓元素把陣列全占滿?試想如果上圖中一圈全有元素了,那麼rear會指向front的那個位置,這時就會出現fro

nt==

rear

front==rear

front=

=rea

r的情況。不覺得眼熟嘛~這就是判斷隊空的條件啊。

所以,如果不在陣列中留乙個空位置的話,隊滿和隊空無法區分。

我看很多教程都會定義乙個佇列的結構體,確實很規範。我把其中的基本原理和操作放在這裡,用起來會比較靈活。以後要寫結構體的話應該也會吧hhhhh

配套練習leetcode127. 單詞接龍 。看懂就要用啊~

迴圈佇列 C語言

佇列的特點是先進先出。在佇列的儲存過程中,不僅使用了一組位址連續的儲存單元存放從佇列頭到佇列尾的元素,而且還附設了兩個指標front和rear,分別指示佇列頭元素及佇列尾元素的位置。佇列操作示意圖 出自嚴蔚敏版資料結構 對鍊錶的增加是通過移動rear指標,鍊錶的刪除時通過移動front的移動。通過這...

迴圈佇列實現(C語言)

背景 生活中有很多佇列的影子,比如打飯排隊,買火車票排隊問題等,可以說與時間相關的問題,一般都會涉及到佇列問題 從生活中,可以抽象出佇列的概念,佇列就是乙個能夠實現 先進先出 的儲存結構。佇列分為鏈式佇列和靜態佇列 靜態佇列一般用陣列來實現,但此時的佇列必須是迴圈佇列,否則會造成巨大的記憶體浪費 鏈...

mysql迴圈佇列 C語言實現 迴圈佇列

include include include typedef struct queue int pbase 陣列 int front 頭 int rear 尾 rear不存放資料,所以rear前面的是最後乙個資料 queue void init queue queue pq bool full q...