一.题目描述
二.题目分析
图中一共有八块空间,是否可以全部用来存储数据呢?
若数据为空,如图所示,front==rear;
若数据满了,如下图所示,front同样和rear一样,指向同一块空间
如何区分呢??
第一种方法:假设一共有k+1个空间,其中k个空间用来存储数据,剩下一个空置,不用来存储,以便区分,队列满时:rear+1=front
第二方法:设置一个size记录元素个数,size==k+1时空间满了,size==0时为空。
这里我们采用第一种方法。
三.顺序表链表的选择
链表
分析: 数据为空时:rear和front指向同一块空间。
数据满时:rear->next==front.
观察题目要求,发现最难搞得就是获取队尾元素
1.采用双向链表
2.增加一个指针,指向rear的前一个
3.遍历一遍找到对位数据
顺序表
在这时候,7还没有插入,但是rear下标越界了,这是一个循环队列,要达到循环的效果,移动rear,如图所示。
(rear+1)%(k+1)
通过观察,两个下标之间相差6,也就是队列元素个数
rear+1=(rear+1)%(k+1)
正常情况下:队列满了,rear+1=front就满了,但是这个rear+1是经过(rear+1)%(k+1)转化过来
所以队列满:(rear+1)%(k+1)==front
队列空:rear==front
我们采用顺序表方式实现。
四.代码实现
//循环队列
typedef struct
{
int*a;
int k;
int rear;
int front;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k)
{
MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//注意,这里的k个空间是用来存储元素的,以免产生分歧,创建k+1个
obj->a=(int*)malloc(sizeof(int)*(k+1));
obj->rear=obj->front=0;
obj->k=k;
return obj;
}
//题目中将以下两个函数接口放到了后面,但是在前面函数中要使用,
//函数要先声明后定义,放到前面就不用生命力,直接使用。
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{
return obj->rear==obj->front;
}
bool myCircularQueueIsFull(MyCircularQueue* obj)
{
return (obj->rear+1)%(obj->k+1)==obj->front;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
if(myCircularQueueIsFull(obj))
{
return false;
}
obj->a[obj->rear]=value;
obj->rear++;
//rear走到最后的位置需要挪到前面去。
obj->rear%=(obj->k+1);
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
if(myCircularQueueIsEmpty(obj))
{
return false;
}
obj->front++;
//front走到最后的位置同样需要挪到前面去。
obj->front%=(obj->k+1);
return true;
}
int myCircularQueueFront(MyCircularQueue* obj)
{
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj)
{
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[(obj->rear+obj->k)%(obj->k+1)];
}
void myCircularQueueFree(MyCircularQueue* obj)
{
free(obj->a);
free(obj);
}
在这里分析一下这段代码
int myCircularQueueRear(MyCircularQueue* obj)
{
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[(obj->rear+obj->k)%(obj->k+1)];
}