1.概念
为充分利用向量空间,克服顺序存储结构的"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量。存储在其中的队列称为循环队列(Circular Queue)。这种循环队列可以以单链表的方式来在实际编程应用中来实现。
循环队列中,由于入队时尾指针向前追赶头指针;出队时头指针向前追赶尾指针,造成队空和队满时头尾指针均相等。因此,无法通过条件front==rear来判别队列是"空"还是"满"。使用求余运算可以判断队列是否已满。
基本操作:
/* 定义链表队列 */
定义结构体中front指示队头位置,rear指示队尾位置,base指针用于申请空间并存放数据。
/* 初始化队列 */
使用指针*base申请100个内存空间,front和rear分别为0,此时队列为空
/* 判断空或满 */
- 初始化时,front = rear = 0 时为空,Q->rear = (0+1)%100 = 1,队列未满可以插入队列
- 入队3个元素时,rear = 3,Q->rear = (3+1)%100 = 4,队列未满
- 入队99个元素时,rear = 99,Q->rear = (99+1)%100 = 0,队列满,不可入队
- 出队2个元素时,front = 2
出队后,执行两次 Q->front = (Q->front + 1) % MAXQSIZE,得到Q->front = 2
- 再次入队1个元素时,rear = 0,Q->rear = (99+1)%100=0,队列未满,可以入队
通用的计算队列长度公式:(rear-front+QueueSize)%QueueSize
#include <stdio.h> #include <stdlib.h> #define OK 1 #define ERROR 0 #define OVERFLOW -2 #define MAXQSIZE 10 typedef int Status; typedef int QElemType; //循环队列的顺序存储结构 typedef struct Node { QElemType *base; //初始化动态分配存储空间 int front;//头指针 int rear;//尾指针-若队列不空,指向队列尾元素的下一个位置 } SqQueue; //初始化一个空的队列 Status InitQueue(SqQueue *Q) { Q->base = (QElemType *)malloc(MAXQSIZE * sizeof(QElemType)); if (!Q->base) exit(OVERFLOW); Q->front = Q->rear = 0; return OK; } //若队列未满 则插入元素elem为Q新的队尾元素 Status EnQueue(SqQueue *Q, QElemType elem) { //队列为空时 1%10==1,队列满时(9+1)%100==0,最多容纳9个元素 if ((Q->rear + 1) % MAXQSIZE == (Q->front))//队列满的判断 return ERROR; Q->base[Q->rear] = elem;//将元素elem赋值给队尾 Q->rear = (Q->rear + 1) % MAXQSIZE; //rear始终在0-10中循环 return OK; } //循环队列的出队列操作代码 Status OutQueue(SqQueue *Q, QElemType *e) { if (Q->front == Q->rear)//队列为空的判断 return ERROR; *e = Q->base[Q->front];//将队头元素赋值给元素e Q->front = (Q->front + 1) % MAXQSIZE;//front指针像后移一位置 return OK; } //遍历整个队列,进行打印操作 Status PrintQueue(SqQueue Q) { printf("the queue is:"); for (int i = Q.front; i < Q.rear; ++i) printf("%d ", Q.base[i]); return OK; } int main() { SqQueue queue; QElemType elem; int i; InitQueue(&queue); printf("input:"); for ( i = 0; i < 10; i++) { elem = i + 1; EnQueue(&queue, elem); } PrintQueue(queue); /* 输入要出队列的个数 */ printf("\noutput:"); scanf("%d", &i); while (i != 0) { OutQueue(&queue, &elem); i--; } PrintQueue(queue); return OK; }