将循环队列想象成圆环结构比较好理解,下面是代码:
//队列,只能从队尾插入,队头输出或者删除 FIFO
//这里的循环队列采用牺牲一个单位空间的办法来区别队列空和满的状态
#define MAXQSIZE 5 //初始最大容量
#define SIZEINCREMENT 5 //每次新增加容量
#include<stdio.h>
#include<stdlib.h>
typedef struct {
int * base; //基址 ,配合front与rear实现随机存取
int front ; //“指向”队头的位置
int rear; //这里rear始终“指向”当前队尾元素的下一位置
int max;
} SqQueue;
void Init_Queue(SqQueue * ); //初始化一个空队列
void Fill_Queue(SqQueue * ); //填充队列
void Judge_Full(SqQueue * ); //判断队列是否满队,若满队增加分配内存
void Print_Queue(SqQueue * ); //输出队列
void Insert_Queue(int ,SqQueue * ); //插入队尾元素
void Delete_Queue(SqQueue * ); //删除队头元素
int main() //测试各函数
{
int e = 100; //测试值
SqQueue * Q;
Q = (SqQueue *)malloc(sizeof(SqQueue )); //初始化指针
Init_Queue(Q);
Fill_Queue(Q);
Print_Queue(Q);
Insert_Queue(e, Q);
Print_Queue(Q);
Delete_Queue(Q);
Print_Queue(Q);
return 0;
}
void Init_Queue(SqQueue * Q)
{
Q->base = (int *)malloc(MAXQSIZE *sizeof( int )); //分配基地址
if(!Q->base) //分配失败
{
printf("Fail to build the queue");
exit(1);
}
Q->front = Q->rear = 0; //队列为空
Q->max = MAXQSIZE; //初始化队列容量
}
void Fill_Queue(SqQueue * Q )
{
int i;
for(i=0;i<9;i++)
{
Judge_Full(Q);
Q->base[Q->rear] = i;
Q->rear = (Q->rear + 1)% Q->max; //rear的值可能会大于Q->max,作为数组下标使用,应进行取模操作
}
}
void Print_Queue(SqQueue * Q)
{
int n = Q->front;
//Q->front的值赋给n,以便其他函数的操作
if(Q->rear == n)
{
printf("the Queue is Empty");
exit(2);
}
printf("the elements of the queue:\n") ;
while(((Q->rear - n + Q->max)% Q->max))
//(Q->rear - Q->front + Q->max)% Q->max 代表队列长度,长度不为零时即队列非空时
{
printf("%d ",Q->base[n]);
n = (n + 1) % Q->max;
}
printf("\n");
}
void Insert_Queue(int e,SqQueue * Q)
{
Judge_Full(Q);
Q->base[Q->rear] = e;
Q->rear = (Q->rear + 1)% Q->max; //队尾指针后移
}
void Judge_Full(SqQueue * Q)
{
if(!((Q->rear + 1 - Q->front)% Q->max)) // (Q->rear + 1 - Q->front)% Q->max 体现了循环队列的特点,想象成圆环状很好理解
{
Q->base = (int *)realloc(Q->base,(MAXQSIZE + SIZEINCREMENT)* sizeof(int *));
if(!Q->base)
{
printf("the Queue is Full but Fail to Realloc");
exit(3);
}
Q->max += MAXQSIZE; //增加容量
}
}
void Delete_Queue(SqQueue * Q)
{
if(Q->rear == Q->front)
{
printf("the Queue is Empty");
exit(4);
}
Q->front = (Q->front + 1)% Q->max; //删除队头元素,队头后移
}