是隊列鴨,FIFO,先進先出!
對於帶頭節點的和不帶頭節點的鏈隊列的操作有個小小的區別:
不帶頭結點的鏈隊列在入隊列的時候,第一個元素時要先判斷是否爲空,再插入。而帶頭結點不需要,操作更方便些;
----------------我是一條分割線---------------------------------------------------------------------
鏈隊列的結構
typedef struct QNode{
Element data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct{
// front,就是隊頭,rear就是隊尾
QueuePtr front,rear;
}LinkQueue;
鏈隊列的操作(不帶頭節點):
// 對於非循環隊列的判讀爲空的條件:隊頭爲空
bool QueueEmpty(LinkQueue *lq){
if (lq->front==NULL){
return true;
}
return false;
}
// 初始化一個不帶頭節點鏈隊列
LinkQueue* LinkQueueInit(){
LinkQueue *lq;
lq = (LinkQueue*)malloc(sizeof(QNode));
lq->front = NULL;
lq->rear = NULL;
return lq;
}
// 入隊列,就是單鏈表的尾插法,rear就是尾指針
Status EnQueue(LinkQueue *lq,Element e){
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if(!p){
return ERROR;
}
p->data = e;
p->next = NULL;
// 判斷是否是一個空的隊列,若是空的隊列,將隊頭和隊尾指向同一節點
if(lq->front == NULL){
lq->front = lq->rear = p;
} else {
lq->rear->next = p;
lq->rear = p;
}
return OK;
}
// 出隊列,從隊頭出,不就和出棧是一樣的嗎
Status DeQueue(LinkQueue *lq,Element *v){
QueuePtr *temp;
if(lq->front == lq->rear){
// QueueEmpty僅僅只是判斷隊頭和隊尾是否指向同一元素節點,當隊頭指向NULL,才說明這個隊列是個空棧隊列
if(QueueEmpty(lq)){
return ERROR;
}
// 當隊列的隊頭和隊尾都指向同一元素節點的時候,將這個節點出隊後,把隊頭和隊尾都置爲空
*v = lq->front->data;
temp = lq->front;
lq->rear = lq->front = NULL;
free(temp);
} else {
*v = lq->front->data;
temp = lq->front;
lq->front = lq->front->next;
free(temp);
}
return OK;
}
void CreateQueue(LinkQueue *lq){
for(int i = 1; i < 5; i++){
EnQueue(lq,i);
}
}
// 清空隊列
void ClearQueue(LinkQueue *lq){
Element e;
Element *resP;
resP = &e;
while(lq->front != NULL){
DeQueue(lq,resP);
}
}
// 打印隊列
void QueuePrint(LinkQueue *lq){
LinkQueue *p = lq;
QueuePtr *hn = lq->front;
printf("隊列中元素按入隊順序依次爲[");
while(p->front){
printf("%d",p->front->data);
if(p->front->next){
printf(", ");
}
p->front = p->front->next;
}
printf("]\n");
lq->front = hn;
}
鏈隊列的操作(帶頭節點的):
// 這裏判環隊列爲空的條件就是隊頭等於隊尾,
bool QueueEmpty(LinkQueue *lq){
if (lq->front == lq->rear){
return true;
}
return false;
}
// 初始化一個帶頭節點鏈隊列
LinkQueue* HLinkQueueInit(){
LinkQueue *lq;
// 申請內存空間
lq = (LinkQueue*)malloc(sizeof(QNode));
// 將front指向一個空的頭節點
lq->rear = lq->front = (QueuePtr *)malloc(sizeof(QNode));
lq->rear->next = NULL;
return lq;
}
Status HEnQueue(LinkQueue *lq,Element e){
// 就是鏈表的尾插法
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if(!p){
return ERROR;
}
p->data = e;
p->next = NULL;
lq->rear->next = p;
lq->rear = p;
return OK;
}
Status HDeQueue(LinkQueue *lq,Element *v){
QueuePtr temp;
if(QueueEmpty(lq)){
return ERROR;
}
temp = lq->front->next;
*v = temp->data;
// 這裏的front一直是沒有變過的,指向一個沒有元素的頭節點。
// 變得只是front的next
lq->front->next = temp->next;
if(p == lq->rear){
lq->rear = lq->front;
}
free(temp);
return OK;
}
// 其他函數都差不太多,就不貼了
運行結果:
不帶頭的。。。
我是分割線----------------------------