1.循环队列的定义
循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。
2.构造循环队列,长度为k
head指向对头,tail指向队尾,但是tail指向的空间没有数据存放,需要一个循环长度为k的循环队列时我们需要构造一个长度为k+1的数组多出来的那个空间用来判断队列是否为空是否为满.
typedef struct {
int* a;
int head;
int tail;
int size;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* My = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
My->size = k;
My->head = 0;
My->tail = 0;
My->a = (int*)malloc(sizeof(int)*(My->size+1));
return My;
}
3.循环队列的数据进出
当我们入数据时再tail指向的空间直接加入数据
但是有一种情况是tail指向了最后一个空间但第一个空间没有数据
当遇到这种情况时我们同样再在tail指向的位置进行入数据
但入完数据之后进行运算
tail = (tail + 1) % (size+1);
使tail回到第一个空间
当这种情况时tail指向空间的下一个位置是head的时候那么这个队列是满的那么这时候就不能再向队列里添加数据
当这种情况时tail和head指向同一个空间时队列是空的
当这种情况head指向队列最后一块空间时要删除数据,删除后需要对head进行运算
head=(head+1)%(size+1)
使head回到队列的第一个空间
代码实现
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if ((obj->tail+1)%(obj->size+1)!=obj->head)
{
obj->a[obj->tail] = value;
obj->tail = (obj->tail + 1) % (obj->size+1);
return true;
}
else
{
return false;
}
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (obj->tail!=obj->head)
{
obj->head=(obj->head+1)%(obj->size+1);
return true;
}
else
{
return false;
}
}
4.取对头的数据
int myCircularQueueFront(MyCircularQueue* obj) {
if (obj->tail==obj->head)
{
return -1;
}
else
{
return obj->a[obj->head];
}
}
5.取队尾的数据
在取队尾的数据时我们同样会遇到这种情况我要要对tail进行运算使它能够指向队尾
tail = (tail + 1) % (size+1);
int myCircularQueueRear(MyCircularQueue* obj) {
if (obj->tail==obj->head)
{
return -1;
}
else
{
return obj->a[(obj->tail+obj->size)%(obj->size+1)];
}
}
6.判断队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
if (obj->head==obj->tail)
{
return true;
}
else
{
return false;
}
}
7.判断队列是否为满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
if ((obj->tail+1)%(obj->size+1)==obj->head)
{
return true;
}
else
{
return false;
}
}
8.释放队列空间
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}
9.整体代码
typedef struct {
int* a;
int head;
int tail;
int size;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* My = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
My->size = k;
My->head = 0;
My->tail = 0;
My->a = (int*)malloc(sizeof(int)*(My->size+1));
return My;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if ((obj->tail+1)%(obj->size+1)!=obj->head)
{
obj->a[obj->tail] = value;
obj->tail = (obj->tail + 1) % (obj->size+1);
return true;
}
else
{
return false;
}
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (obj->tail!=obj->head)
{
obj->head=(obj->head+1)%(obj->size+1);
return true;
}
else
{
return false;
}
}
int myCircularQueueFront(MyCircularQueue* obj) {
if (obj->tail==obj->head)
{
return -1;
}
else
{
return obj->a[obj->head];
}
}
int myCircularQueueRear(MyCircularQueue* obj) {
if (obj->tail==obj->head)
{
return -1;
}
else
{
return obj->a[(obj->tail+obj->size)%(obj->size+1)];
}
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
if (obj->head==obj->tail)
{
return true;
}
else
{
return false;
}
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
if ((obj->tail+1)%(obj->size+1)==obj->head)
{
return true;
}
else
{
return false;
}
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}