爲什麼要用循環隊列,及基礎操作代碼(c語言)~DS筆記④

隊列

一種重要的數據結構。它常常和放在一起作比較,因爲一個是先進先出,另一個是後進先出
什麼意思呢?就好比你去排隊買票,那你越早排,也就越早買到票。這就像隊列結構。也就是’‘先進先出’’。
怎麼實現呢?可能你會說做一個數組一個隊頭指針一個隊尾指針
就像下面這樣:

queue
沒錯,這就是一個隊列了。
但是,一般隊列不這麼做,爲什麼?
比如我們有了新元素要入隊,又有元素要出對,怎麼辦?
那應該是下圖這樣:
queue
看起來好像沒什麼毛病,可是一直這麼出隊,入隊,再出隊再入隊,結果會怎樣呢?
如下圖:
queue
那麼總有一天,隊頭指針會走到隊尾。
也就是說,終有一天,隊伍有效長度會爲零
如下圖:
queue
可能你要說,那每次出隊後讓所有元素前移一位不行?
可以是可以,但這就增加了代碼的時間複雜度,是冗餘的開銷。
當然,理論上你還可以讓隊伍足夠長,但這也是不現實,不合理的。
那怎麼解決這個問題呢?
這就是我們經常用到的:

循環隊列

換言之,一般隊列的弊端在於,如果不進行前移操作,那麼隊列隊頭指針終會到頭。
那如果我們的隊列沒有隊尾呢?
沒錯,循環隊列就是一個‘‘’’,當然,這是邏輯結構,實際的物理存儲方式還是和數組一樣的。
如下圖:

1
比如我們有元素要入對:
2
比如我們有元素出隊:
3
我們可以隨性所欲的進行入隊,出隊操作,而不必擔心數組長度了。
而無論是時間複雜度,還是空間複雜度,我們都沒有多餘的增長

循環隊列(順序存儲)

初始設定:

#include<stdio.h>
#define MAXSIZE 20  //存儲空間初始分配量
typedef int QElemType; //類型根據情況而定,這裏設爲int
typedef enum{ False = 0, True = 1 }Bool;

結構體:

typedef struct
{//循環隊列的順序存儲結構
 QElemType data[MAXSIZE];
 int front;     //頭指針
 int rear;  //尾指針,若隊列不空,指向隊列尾元素的下一個位置
}SqQueue;

基本操作:

訪問:
Bool visit(QElemType c)
{//訪問輸出
 printf("%d ", c);
 return True;
}
遍歷:
Bool QueueTraverse(SqQueue* Q)
{//隊列遍歷
 int i;
 i = Q->front;
 while (i != Q->rear)
 {//遍歷隊列
  visit(Q->data[i]);//訪問輸出
  i = (i + 1) % MAXSIZE;//下標i每次加一
 }
 puts("");
 return True;
}
初始化:
Bool InitQueue(SqQueue* Q)
{//初始化一個空隊列Q
 Q->front = 0;
 Q->rear = 0;
 return True;
}
是否爲空:
Bool QueueEmpty(SqQueue* Q)
{/* 若隊列Q爲空隊列,則返回True,否則返回False */
 if (Q->front == Q->rear) /* 隊列空的標誌 */
  return True;
 else
  return False;
}
返回長度:
int QueueLength(SqQueue* Q)
{/* 返回Q的元素個數,也就是隊列的當前長度 */
 return  (Q->rear - Q->front + MAXSIZE) % MAXSIZE;
}

入隊:

Bool EnQueue(SqQueue* Q, QElemType e)
{
 if ((Q->rear + 1) % MAXSIZE == Q->front)/* 隊列滿的判斷 */
  return False;
 Q->data[Q->rear] = e;/* 將元素e賦值給隊尾 */
 Q->rear = (Q->rear + 1) % MAXSIZE;/* rear指針向後移一位置 */
 return True;
}

出隊:

Bool DeQueue(SqQueue* Q, QElemType *e)
{
 if (Q->front == Q->rear)/* 隊列空的判斷 */
  return False;
 *e = Q->data[Q->front];//將隊頭元素賦給e
 Q->front = (Q->front + 1) % MAXSIZE;/* front指針向後移一位置 */
 return True;
}

謝觀~
再加一句,這兒有一個我在棧那一篇就介紹過的一個網站,可以實現隊列的可視化操作:
https://visualgo.net/zh/list
(在網頁上面菜單欄選擇隊列)
(:з)∠)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章