文章目录
- 1.思路分析
- 1.1队列空满分析
- 1.2出队分析
- 2.循环队列设计
1.思路分析
1.1队列空满分析
首先我们假设一个长度为4的环形队列
队头front
队尾rear
当队列为空时
front=rear
当队列满时
front=rear
所以我们无法判断队列是满的或者空的
因此我们多加入一个空间使队列长度为5,我们使real的值为队尾的下一个下标
这种情况下
当队列为空时
front=rear
当队列满时
real+1=front
这样我们就有了判断空满的能力
但是
这种情况下显然是满了但是
rear+1=5
front=0
显然不相等
所以我们需要改进
判断满的条件为(rear+1)%(k+1)
进而推出下标在循环里的判断方式
(real/front)%(k+1)
1.2出队分析
出队
出头
return obj->a[obj->front];
出尾
出尾我们要给real-1
当然还有特殊情况
这种我们没办法-1,所以要改变我们的判定方式为
(rear+k)%(k+1)
return obj->a[(obj->rear+obj->k)%(obj->k+1)];
总结
当然上述方法也可以单把特殊情况拿出来写,我这里就不写了
2.循环队列设计
typedef struct {
int *a;
int front;
int rear;
int k;
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
assert(obj);
return obj->front==obj->rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
assert(obj);
return ((obj->rear+1)%(obj->k+1))==obj->front;
}
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a=(int*)malloc(sizeof(int)*(k+1));
obj->front=obj->rear=0;
obj->k=k;
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
assert(obj);
if(myCircularQueueIsFull(obj))
return false;
else
obj->a[obj->rear++]=value;
obj->rear%=obj->k+1;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
assert(obj);
if(myCircularQueueIsEmpty(obj))
return false;
else
obj->front++;
obj->front%=obj->k+1;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
assert(obj);
if(myCircularQueueIsEmpty(obj))
return -1;
else
return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
assert(obj);
if(myCircularQueueIsEmpty(obj))
return -1;
else
return obj->a[(obj->rear+obj->k)%(obj->k+1)];
}
void myCircularQueueFree(MyCircularQueue* obj) {
assert(obj);
free(obj->a);
free(obj);
}