普通队列存在假溢出的问题, 循环队列通过空出一个空间结合取余操作可以实现对空间的充分利用。
1.循环队列的定义:
typedef struct queue{
int *data;
int front;
int rear;
}queue, *Queue;
2.循环队列的初始化:
循环队列的元素存储在结构体的data指针域里, 所以需要先给data分配空间
Q.data = new int[maxsize];
同时将头指针与尾指针置为0。
3.循环队列的入队操作:
直接将data元素赋值给rear指向的区域:
Q.data[Q.rear] = data;
由于是循环, 尾指针应+1后对最大值取余, 该操作为了rear到达最大值后回到0的位置, 达到循环的功能。
Q.rear = (Q.rear+1)%maxsize;
4.循环队列的出队操作:
直接取出头指针元素即可, 同时头指针向上移动进行取余操作。
5.循环队列求长度:
求长度分为两种情况:
1.当rear > front时:长度为 rear - front
2.当rear < front 时, 长度为rear - front + maxsize
因此求长公式:
(Q.rear - Q.front + maxsize) % maxsize;
6.判断队空与队满:
由于rear指针总是指向末尾元素的下一位, 因此队空条件为:
Q.front == Q.rear
队满条件为:
Q.front == (Q.rear + 1) % maxsize;
源代码
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct queue{
int *data;
int front;
int rear;
}queue, *Queue;
int maxsize;
int QueueInit(queue & Q){
Q.data = new int[maxsize];
if(!Q.data){
printf("创建失败!\n");
exit(0);
}
Q.front = 0; Q.rear = 0;
return 1;
}
int QueueLength(queue Q){
return (Q.rear - Q.front + maxsize) % maxsize;
}
void QueuePush(queue & Q, int data){
Q.data[Q.rear] = data;
Q.rear = (Q.rear+1)%maxsize;
}
int QueuePop(queue &Q){
int data = Q.data[Q.front];
printf("%d\n", data);
Q.front = (Q.front + 1) % maxsize;
}
int QueueEmpty(queue Q){
return Q.front == Q.rear;
}
int QueueMax(queue Q){
return Q.front == (Q.rear + 1) % maxsize;
}
void QueueTravel(queue Q){
int s = Q.front;
while(s != Q.rear){
printf("%d ", Q.data[s]);
s = (s + 1) % maxsize;
}
printf("\n");
}
void QueueClear(queue & Q){
Q.front = Q.rear;
}
int main(){
int t;
printf("输入队列容量:");
scanf("%d", &maxsize);
queue q;
QueueInit(q);
while(1){
printf("1.输入:\n");
printf("2.长度:\n");
printf("3.遍历:\n");
printf("4.获取头元素:\n");
printf("5.弹出头元素:\n");
printf("6.清空队列:\n");
printf("请输入你的操作:");
scanf("%d", &t);getchar();
switch(t){
case 1:{
int data;
if(QueueMax(q)){
printf("队列已满!\n");
}else{
scanf("%d", &data);
QueuePush(q, data);
break;
}
}
case 2:{
printf("长度为:%d\n", QueueLength(q));
break;
}
case 3:{
QueueTravel(q);
break;
}
case 4:{
printf("%d\n", q.data[q.front]);
break;
}
case 5:{
if(QueueEmpty(q)){
printf("队列为空!\n");
}else{
QueuePop(q);
}
break;
}
case 6:{
QueueClear(q);
printf("队列已清空!\n");
break;
}
default:{
printf("输入错误, 请重试!\n");
break;
}
}
}
return 0;
}