设计循环队列
文章目录
一、题目
二、思路分析
1. 循环队列构成分析
循环队列的想象图:
循环队列的实际操作图:(这里数组和链表都可以)
- 这里当
front
和tail
相等的时候是空队列
以 数组为例
插入元素1
插入元素2
插入元素3
当 插入满
的时候
- 此时也是
front
和tail
相等的时候是队列满了
所以我们发现这样空队列和满队列的判断就出了问题
这里也需要一个 空间去把头和尾隔开
我们认为在这个时候,队列就满了,实际队列长度是3
,实际数组长度是4
2. 循环队列定义
typedef struct {
int* a;//数组
int front;//记录头
int tail;//记录尾
int k;//设定队列长度
} MyCircularQueue;
3. 循环队列初始化
注意k + 1
,这里才是数组真正的长度,使用者并不知道
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
cq->a = malloc(sizeof(int) * (k + 1));//这里k + 1 很重要
cq->front = 0;//置空
cq->tail = 0;//置空
cq->k = k;//赋值
return cq;
}
4. 循环队列插入一个元素
这里需要判断队列满了
没有
满的时候,满足tail + 1 = front
,相差1
但我们tail
加1
需要变成0
这里就需要**%
上一个链表的长度**
//队列满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail + 1) % (obj->k + 1) == obj->front;
}
//向循环队列插入一个元素。如果成功插入则返回真。
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
//先判断循环队列满了没有
if(myCircularQueueIsFull(obj))
{
return false;
}
obj->a[obj->tail] = value;
obj->tail = (obj->tail + 1) % (obj->k + 1);
return true;
}
5. 循环队列中删除一个元素
这里需要先判断要删除的队列是不是空队列
front
和 tail
相等的时候为空
删除一个元素 front
就往后加
//队列空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front == obj->tail;
}
//从循环队列中删除一个元素。如果成功删除则返回真。
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
//先判断队列是不是空
if(myCircularQueueIsEmpty(obj))
{
return false;
}
obj->front = (obj->front + 1) % (obj->k + 1);
return true;
}
6. 队首获取元素
先判空,再取front
对应数值
// 从队首获取元素。如果队列为空,返回 -1 。
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[obj->front];
}
7. 队尾获取元素
拿到队尾元素就复杂了很多
因为tail
和队尾元素一直差1
单单tail - 1
去得到元素是不行的
出现这种情况:
tail + k
,这里k
比一个循环少1
,再%
一个循环k + 1
,最终得到tail
会少1
// 获取队尾元素。如果队列为空,返回 -1 。
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[(obj->tail + obj->k) % (obj->k + 1)];
}
8. 销毁循环链表
//销毁循环链表
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a = NULL;
obj->k = 0;
obj->front = 0;
obj->tail = 0;
free(obj);
}