一、概念与结构
循环队列是一种特殊的队列,首尾相连成环,也叫环形队列。环形队列具有以下三个特点:
(1)队头删除数据,队尾插入数据。
(2)给定固定的空间,使用过程中不能扩容。
(3)环形队列满了之后,不能继续插入数据(即插入数据失败)。
环形队列可以使用数组实现,也可以使用循环链表实现。使用数组实现的话更简单。定义头指针front和尾指针rear。当rear指向最后一个元素的时候,我们只需要让rear % 空间大小就可以让rear指针重新指向front。

但是,这样又带来一个问题,当环形队列为空时:front == rear;当环形队列满了:front == rear。那么,我们该如何区分环形队列是空还是满呢?我们可以在结构体中再定义一个size变量,用于统计环形队列中有效数据的个数。但是这样又要额外开辟四个字节的空间,有没有更好的办法呢?我们额外申请一块空间,但这块空间不保存任何数据,这样就不用额外增加结构体的成员变量。

此时,rear == front表示环形队列为空;如果满足(rear + 1)%(k + 1)== front,表示环形队列满了。
二、题目描述
https://leetcode.cn/problems/design-circular-queue

三、参考代码
typedef struct
{
int* arr;
int front;//队头
int rear;//队尾
int capacity;//循环队列的空间大小
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k)
{
MyCircularQueue* pq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//申请k+1个空间
pq->arr = (int*)malloc((k + 1) * sizeof(int));
pq->front = pq->rear = 0;
pq->capacity = k;
return pq;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{
return obj->front == obj->rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj)
{
return (obj->rear + 1) % (obj->capacity + 1) == obj->front;
}
//向循环队列中插入一个元素
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
//先判断是否满了
if(myCircularQueueIsFull(obj))
{
return false;
}
//没有满
else
{
obj->arr[obj->rear++] = value;
obj->rear %= obj->capacity + 1;
return true;
}
}
//从循环队列中删除一个元素
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
if(myCircularQueueIsEmpty(obj))
{
return false;
}
//非空
else
{
obj->front++;
obj->front %= obj->capacity + 1;
return true;
}
}
int myCircularQueueFront(MyCircularQueue* obj)
{
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->arr[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj)
{
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
int prev = obj->rear - 1;
if(obj->rear == 0)
{
prev = obj->capacity;
}
return obj->arr[prev];
}
void myCircularQueueFree(MyCircularQueue* obj)
{
if(obj->arr)
free(obj->arr);
obj->arr = NULL;
obj->front = obj->rear = obj->capacity = 0;
free(obj);
obj = NULL;
}
/**
* Your MyCircularQueue struct will be instantiated and called as such:
* MyCircularQueue* obj = myCircularQueueCreate(k);
* bool param_1 = myCircularQueueEnQueue(obj, value);
* bool param_2 = myCircularQueueDeQueue(obj);
* int param_3 = myCircularQueueFront(obj);
* int param_4 = myCircularQueueRear(obj);
* bool param_5 = myCircularQueueIsEmpty(obj);
* bool param_6 = myCircularQueueIsFull(obj);
* myCircularQueueFree(obj);
*/
4507

被折叠的 条评论
为什么被折叠?



