队列循环
设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
你的实现应该支持如下操作:
MyCircularQueue(k)
: 构造器,设置队列长度为 k 。Front
: 从队首获取元素。如果队列为空,返回 -1 。Rear
: 获取队尾元素。如果队列为空,返回 -1 。enQueue(value)
: 向循环队列插入一个元素。如果成功插入则返回真。deQueue()
: 从循环队列中删除一个元素。如果成功删除则返回真。isEmpty()
: 检查循环队列是否为空。isFull()
: 检查循环队列是否已满。
整体思路解析:
1、利用malloc开辟一个数组的空间在里面存储数据。
2、利用back和front去寻找首元素和尾元素。
3、利用对元素k的取模重置back和front。
结构体定义
tip:自己需要什么方便解题就怎么来。
思路解析:
需要使用back、front、一个指向数组的指针和为了重置back和front的元素k.
代码展示:
typedef struct {
int *a;
int back;
int front;
int k;
} MyCircularQueue;
MyCircularQueue(k)
: 构造器,设置队列长度为 k 。
思路解析:
开辟一个结构体的空间和一个数组的空间然后把数据都置为空返回结构体即可。
代码展示:
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a=(int*)malloc(sizeof(int)*(k+1));
obj->back=0;
obj->front=0;
obj->k=k;
return obj;
}
Front
: 从队首获取元素。如果队列为空,返回 -1 。
思路解析:
对目标进行判断(利用empty函数)如果为空就返回-1,不为空就利用front去访问数组即可。
代码展示:
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[obj->front];
}
Rear
: 获取队尾元素。如果队列为空,返回 -1 。
思路解析:
利用元素k重置back,使back重新从第一个数据开始往后走。
代码展示:
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return -1;
}
return obj->a[(obj->back+(obj->k+1)-1)%(obj->k+1)];
}
v
enQueue(value)
: 向循环队列插入一个元素。如果成功插入则返回真。
思路解析:
直接使用back进行数据的插入,然后后置加加最后利用k元素把back重置到数组的第一个位置。
代码展示:
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;
}
deQueue()
: 从循环队列中删除一个元素。如果成功删除则返回真。
思路解析:
因为是直接用front进行访问所以直接利用front++即可。
代码展示:
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
{
return false;
}
obj->front++;
(obj->front)%=(obj->k+1);
return true;
}
isEmpty()
: 检查循环队列是否为空。
思路解析:
所以判断是否为空直接就是看back和front是否相等,初始化都赋的是0。
代码展示:
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->back==obj->front;
}
isFull()
: 检查循环队列是否已满。
思路解析:
因为初始化时back和front是都赋为0的要是空间都满了的情况back的下一个就是front,利用元素k使back重新从第一个位置开始。
代码展示:
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->back+1)%(obj->k+1)==obj->front;
}
数据销毁
思路解析:
先freemalloc出来的数组然后把malloc出来的结构体也一起free即可。
代码展示:
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}