1. 入隊(duì)操作
如圖,進(jìn)行入隊(duì)(push)操作的時(shí)候,我們首先需要特判一下隊(duì)列是否為空,如果隊(duì)列為空的話,需要將頭指針和尾指針一同指向第一個(gè)結(jié)點(diǎn),即front=n;rear=n。
當(dāng)如果隊(duì)列不為空的時(shí)候,我們只需要將尾結(jié)點(diǎn)向后移動(dòng),通過不斷移動(dòng)next指針指向新的結(jié)點(diǎn)構(gòu)成隊(duì)列即可。
其代碼可以表示為:
//入隊(duì)操作 void push(queue *q,int data){ node *n =init_node(); n->data=data; n->next=NULL; //采用尾插入法 //if(q->rear==NULL){ //使用此方法也可以 if(empty(q)){ q->front=n; q->rear=n; }else{ q->rear->next=n; //n成為當(dāng)前尾結(jié)點(diǎn)的下一結(jié)點(diǎn) q->rear=n; //讓尾指針指向n } }
2. 出隊(duì)操作
出隊(duì)(pop)操作,是指在隊(duì)列不為空的情況下(請(qǐng)注意一定要進(jìn)行隊(duì)列判空的操作),進(jìn)行一個(gè)判斷,如圖,如果隊(duì)列只有一個(gè)元素了(即頭尾指針均指向了同一個(gè)結(jié)點(diǎn)),直接將頭尾兩指針制空(NULL)并釋放這一個(gè)結(jié)點(diǎn)即可。
如圖,當(dāng)隊(duì)列含有二以上個(gè)元素時(shí),我們需要將隊(duì)列的頭指針指向頭指針當(dāng)前指向的下一個(gè)元素并釋放掉當(dāng)前元素即可。
其代碼可以表示為:
//出隊(duì)操作 void pop(queue *q){ node *n=q->front; if(empty(q)){ return ; //此時(shí)隊(duì)列為空,直接返回函數(shù)結(jié)束 } if(q->front==q->rear){ q->front=NULL; //只有一個(gè)元素時(shí)直接將兩端指向制空即可 q->rear=NULL; free(n); //記得歸還內(nèi)存空間 }else{ q->front=q->front->next; free(n); } }
3. 打印隊(duì)列元素(遍歷)
打印隊(duì)列的全部元素是在隊(duì)列不為空的情況下,通過結(jié)點(diǎn)的next指向依次遍歷并輸出元素既可以。
其代碼可以表示為
//打印隊(duì)列元素 void print_queue(queue *q){ node *n = init_node(); n=q->front; if(empty(q)){ return ; //此時(shí)隊(duì)列為空,直接返回函數(shù)結(jié)束 } while (n!=NULL){ printf("%d\t",n->data); n=n->next; } printf("\n"); //記得換行 }
遍歷操作還有很多變形,比如說進(jìn)行計(jì)算隊(duì)列中含有多少元素。
int calac(queue *q){ node *n = init_node(); n=q->front; int cnt=0; //計(jì)數(shù)器設(shè)計(jì) if(empty(q)){ return 0; //此時(shí)隊(duì)列為空,直接返回函數(shù)結(jié)束 } while (n!=NULL) { n=n->next; cnt++; } return cnt; }
4. 代碼實(shí)現(xiàn)
#include<stdio.h> #include<stdlib.h> //結(jié)點(diǎn)定義 typedef struct node{ int data; struct node *next; }node; //隊(duì)列定義,隊(duì)首指針和隊(duì)尾指針 typedef struct queue{ node *front; node *rear; }queue; //初始化結(jié)點(diǎn) node *init_node(){ node *n=(node*)malloc(sizeof(node)); if(n==NULL){ //建立失敗,退出 exit(0); } return n; } //初始化隊(duì)列 queue *init_queue(){ queue *q=(queue*)malloc(sizeof(queue)); if(q==NULL){ //建立失敗,退出 exit(0); } //頭尾結(jié)點(diǎn)均賦值NULL q->front=NULL; q->rear=NULL; return q; } //隊(duì)列判空 int empty(queue *q){ if(q->front==NULL){ return 1; //1--表示真,說明隊(duì)列非空 }else{ return 0; //0--表示假,說明隊(duì)列為空 } } //入隊(duì)操作 void push(queue *q,int data){ node *n =init_node(); n->data=data; n->next=NULL; //采用尾插入法 //if(q->rear==NULL){ if(empty(q)){ q->front=n; q->rear=n; }else{ q->rear->next=n; //n成為當(dāng)前尾結(jié)點(diǎn)的下一結(jié)點(diǎn) q->rear=n; //讓尾指針指向n } } //出隊(duì)操作 void pop(queue *q){ node *n=q->front; if(empty(q)){ return ; //此時(shí)隊(duì)列為空,直接返回函數(shù)結(jié)束 } if(q->front==q->rear){ q->front=NULL; //只有一個(gè)元素時(shí)直接將兩端指向制空即可 q->rear=NULL; free(n); //記得歸還內(nèi)存空間 }else{ q->front=q->front->next; free(n); } } //打印隊(duì)列元素 void print_queue(queue *q){ node *n = init_node(); n=q->front; if(empty(q)){ return ; //此時(shí)隊(duì)列為空,直接返回函數(shù)結(jié)束 } while (n!=NULL) { printf("%d\t",n->data); n=n->next; } printf("\n"); //記得換行 } //主函數(shù)調(diào)用,這里只是簡單介紹用法 int main(){ queue *q=init_queue(); ///////////////入隊(duì)操作///////////////// printf("入隊(duì)\n"); for(int i=1;i<=5;i++){ push(q,i); print_queue(q); } ///////////////出隊(duì)操作///////////////// printf("出隊(duì)\n"); for(int i=1;i<=5;i++){ pop(q); print_queue(q); } return 0; }
5. 配套題目推薦
對(duì)于基本的操作,可以同鏈表的題目測試,自定義一些數(shù)據(jù)集來測試,這里不再提供直接的問題鏈接,其次可以試著去做一些基本的隊(duì)列操作的題目,如:
接著,隊(duì)列的操作會(huì)在很多的算法設(shè)計(jì)中使用到,尤其是BFS(廣度優(yōu)先搜索)算法的設(shè)計(jì)和一些圖論的算法設(shè)計(jì)幾乎無法離開各種類型的隊(duì)列的靈活使用。
對(duì)于本樣例代碼,同學(xué)們可以試將隊(duì)列元素?cái)?shù)量設(shè)計(jì)入結(jié)構(gòu)體中,這樣每次詢問隊(duì)列中含有多少元素時(shí)就不必在進(jìn)行依次遍歷出元素?cái)?shù)量而直接出答案了。
1895 | 藍(lán)橋杯算法提高VIP-隊(duì)列操作 |
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:
一點(diǎn)編程也不會(huì)寫的:零基礎(chǔ)C語言學(xué)練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進(jìn)階課程
從零到寫出一個(gè)爬蟲的Python編程課程
只會(huì)語法寫不出代碼?手把手帶你寫100個(gè)編程真題的編程百練課程
信息學(xué)奧賽或C++選手的 必學(xué)C++課程
藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競賽課入門課程
手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程