生活中有不少隊列的影子,好比打飯排隊,買火車票排隊問題等,能夠說與時間相關的問題,通常都會涉及到隊列問題;從生活中,能夠抽象出隊列的概念,隊列就是一個可以實現「先進先出」的存儲結構。隊列分爲鏈式隊列和靜態隊列;靜態隊列通常用數組來實現,但此時的隊列必須是循環隊列,不然會形成巨大的內存浪費;鏈式隊列是用鏈表來實現隊列的。這裏講的是循環隊列,首先咱們必須明白下面幾個問題算法
1、循環隊列的基礎知識數組
1.循環隊列須要幾個參數來肯定ui
循環隊列須要2個參數,front和rearspa
2.循環隊列各個參數的含義code
(1)隊列初始化時,front和rear值都爲零;blog
(2)當隊列不爲空時,front指向隊列的第一個元素,rear指向隊列最後一個元素的下一個位置;隊列
(3)當隊列爲空時,front與rear的值相等,但不必定爲零;內存
3.循環隊列入隊的僞算法it
(1)把值存在rear所在的位置;class
(2)rear=(rear+1)%maxsize ,其中maxsize表明數組的長度;
程序代碼:
if(IsFullQueue(Q)) return 0; else { Q->pBase[Q->rear]=val; Q->rear=(Q->rear+1)%Q->maxsize; } return 1;
4.循環隊列出隊的僞算法
(1)先保存出隊的值;
(2)front=(front+1)%maxsize ,其中maxsize表明數組的長度;
程序代碼:
if(IsEmptyQueue(Q)) { return 0; } else { *val=Q->pBase[Q->front]; Q->pBase[Q->front]=0; Q->front=(Q->front+1)%Q->maxsize; } return 1;
5.如何判斷循環隊列是否爲空
if(front==rear)
隊列空;
else
隊列不空
程序代碼:
if(Q->front==Q->rear) //判斷是否爲空 return 1; else return 0;
6.如何判斷循環隊列是否爲滿
這個問題比較複雜,假設數組的存數空間爲7,此時已經存放1,a,5,7,22,90六個元素了,若是在往數組中添加一個元素,則rear=front;此時,隊列滿與隊列空的判斷條件front=rear相同,這樣的話咱們就不能判斷隊列究竟是空仍是滿了;
解決這個問題有兩個辦法:一是增長一個參數,用來記錄數組中當前元素的個數;第二個辦法是,少用一個存儲空間,也就是數組的最後一個存數空間不用,當(rear+1)%maxsiz=front時,隊列滿。
程序代碼:
if(Q->front==(Q->rear+1)%Q->maxsize) //判斷循環鏈表是否滿,留一個預留空間不用 return 1; else return 0;
附錄:
queue.h文件代碼:
#ifndef _QUEUE_SELF_H_ #define _QUEUE_SELF_H_ #include <stdint.h> typedef struct queue { uint16_t *pBase; int16_t front; //指向隊列第一個元素下標 int16_t rear; //指向隊列最後一個元素的下一個元素的下標 int16_t maxsize; //循環隊列的最大存儲空間 }QUEUE,*PQUEUE; uint8_t CreateQueue(PQUEUE Q,int16_t maxsize); uint8_t IsFullQueue(PQUEUE Q); uint8_t IsEmptyQueue(PQUEUE Q); uint8_t SendtoBackQueue(PQUEUE Q, uint16_t val); uint8_t ReceivefromFrontQueue(PQUEUE Q, uint16_t *val); #endif /* _QUEUE_SELF_H_ */
queue.c文件代碼:
#include"queue_self.h" #include "stdlib.h" uint8_t CreateQueue(PQUEUE Q,int16_t maxsize) { Q->pBase=(uint16_t *)malloc(sizeof(uint16_t)*maxsize); if(NULL==Q->pBase) exit(-1); //退出程序 Q->front=0; //初始化參數 Q->rear=0; Q->maxsize=maxsize; return 1; } uint8_t IsFullQueue(PQUEUE Q) { if(Q->front==(Q->rear+1)%Q->maxsize) //判斷循環鏈表是否滿,留一個預留空間不用 return 1; else return 0; } uint8_t IsEmptyQueue(PQUEUE Q) { if(Q->front==Q->rear) //判斷是否爲空 return 1; else return 0; } uint8_t SendtoBackQueue(PQUEUE Q, uint16_t val) { if(IsFullQueue(Q)) return 0; else { Q->pBase[Q->rear]=val; Q->rear=(Q->rear+1)%Q->maxsize; } return 1; } uint8_t ReceivefromFrontQueue(PQUEUE Q, uint16_t *val) { if(IsEmptyQueue(Q)) { return 0; } else { *val=Q->pBase[Q->front]; Q->pBase[Q->front]=0; Q->front=(Q->front+1)%Q->maxsize; } return 1; }