设计你的循环队列实现。循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
数组实现循环队列
主要难点在于如何判断满队列与空队列--->通过增加成员size或者多开辟一块空间;
front与back都从0开始,那么back下标指的就是队尾的下一个;
还要注意有back跑到front前面的情况,但是数据个数自始至终都是front数到back即[front,back) 思路如下:
结构
typedef struct {
int* a;
int k;//数据个数
int front;//队头-下标
int back;//队尾-下标
} MyCircularQueue;
初始化
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* mcq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
mcq->a = (int*)malloc(sizeof(int) * (k + 1));//k个数据的队列开k+1个空间
mcq->k = k;
mcq->front = 0;
mcq->back = 0;
return mcq;
}
判断空队列
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front == obj->back;
}
判断满队列
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->back + 1) % (obj->k + 1) == obj->front;
}
插入
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if (myCircularQueueIsFull(obj))
return false;
obj->a[obj->back] = value;
obj->back++;//可能越界
obj->back %= (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->back - 1 + obj->k + 1) % (obj->k + 1)];
}
释放空间
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}