如果要用数组实现循环队列,需要在包含数组的结构体中定义两个变量用于表示数组的下标,第一个下标front表示队列的头,第二个下标rear表示队列的尾。
队列的特点是先进先出,除此之外我们还应该知道循环队列的的大小是 提前设定好的,因此队列大小以及结构体定义如下:
1.队列结构体定义:
#define MAXSIZE 6 //队列容量
typedef struct Queue
{
int front;
int rear;
int list[MAXSIZE];
}Queue;
2.队列初始化
队列的初始化:向内存申请一片空间用于存放该队列,初始化的时候队列是空的,因此front=rear=0;
Queue * lpQInit()
{
Queue* queue=(Queue*)malloc(sizeof(Queue));
queue->front=queue->rear=0;
return queue;
}
3.入队前的判定:队列是否已满
队列的入队操作前,需要判定此时的队列是否已经满了,判断的条件是:(rear+1)%MAXSIZE==front,我们不能用rear==front这样的条件去判断,因为队列空的时候的判断条件就是如此,这样就重复了,因此我们宁愿牺牲一部分空间,也换取尾指针在队满的情况下处于头指针的前一个。
int isFull(Queue* queue)
{
if((queue->rear+1)%MAXSIZE==queue->front)
return 1;
else
return 0;
}
4.入队操作
入队操作时,把值给尾指针指向的那个下标,然后尾指针向后移。此时我们只考虑了队空的情况,那么队满的时候呢?队满的时候,我们需要先将出队一个元素,然后再入队,
int ruQueue(Queue* queue,int data)
{
if(isFull(queue))
{
printf("loop queue is FULL");
return 0;
}
else
{
//xian add data
queue->list[queue->rear]=data;
//zai ba rear xiang hou yi
queue->rear=(queue->rear+1)%MAXSIZE;
}
}
//上面的是原先写的,下面的是后面写的,下面的考虑了队满之后的实时更新队列的情况
int push_queue(Queue_p queue,data_t data)
{
if(NULL==queue)
{
printf("queue is null\n");
return -1;
}
if(1==isFull(queue))
{
printf("queue is full\n");
pop_queue(queue); //出队
push_queue(queue,data);
}
else
{
queue->buf[queue->tail]=data;
queue->tail=(queue->tail+1)%N;
}
}
5.出队前的判定:队列是否为空
之前已经提到了,队列为空的判定条件是rear==front
int isEmpty(Queue* queue)
{
if(queue->front==queue->rear)
{
return 1;
}
else
return 0;
}
6.出队操作
出队时,是从头指针的位置取元素,可以打印辅助信息确定出队的数据是什么,然后让头指针向后移
int chuQueue(Queue* queue)
{
if(isEmpty(queue))
{
printf("loop queue is NULL\n");
return 0;
}
else
{
//huo de chu dui de zhi
int a=queue->list[queue->front];
queue->front=(queue->front+1)%MAXSIZE;
printf("chu dui :%d\n",a);
return a;
}
}
7.遍历循环队列
遍历循环队列时需要注意的是:首先我们需要知道此时的队列有几个元素,通过(rear-front+MAXSIZE)%MAXSIZE得到元素个数,为什么尾指针减去头指针还要加上MAXSIZE呢,因为这是循环队列,可能尾指针的下标比头指针小,那样相减的话会出现负值,导致越界。
其次我们需要一个临时变量index从队列的头部开始进行遍历。
void print(Queue* queue)
{
int len=(queue->rear-queue->front+MAXSIZE)%MAXSIZE;
int index=queue->front;
printf("Queue: ");
for(int i=0;i<len;i++)
{
printf("%d--->",queue->list[index]);
index=(index+1)%MAXSIZE;
}
printf("\n");
}
8.main函数中的入队与出队代码:
int main(int argc,char *argv[])
{
Queue* queue=lpQInit();
ruQueue(queue,1);
print(queue);
ruQueue(queue,2);
print(queue);
ruQueue(queue,3);
print(queue);
chuQueue(queue);
print(queue);
}
运行效果: