目录
1.循环队列的基础结构
循环队列是一种基于数组实现的队列,具有头指针front和尾指针rear。front指向队头元素,rear指向队尾元素的下一个位置,这样空队列时,front == rear;而队列满时,(rear+1)%n == front,其中n为数组的大小,表示rear再循环一圈后到达队头位置。
因此我们可以得到它的基础结构如下
typedef struct
{
int* a;
int front;
int rear;
int k;
} MyCircularQueue;
2.循环队列的数据操作
①判断循环队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{
if (obj->rear == obj->front)
{
return true;
}
else
{
return false;
}
}
②判断循环队列是否为满
bool myCircularQueueIsFull(MyCircularQueue* obj)
{
if ((obj->rear + 1) % (obj->k + 1) == obj->front)
{
return true;
}
else
{
return false;
}
}
③创建循环队列
MyCircularQueue* myCircularQueueCreate(int k)
{
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
if (obj == NULL)
{
perror("malloc fail");
return NULL;
}
int* tmp = (int*)malloc(sizeof(int) * (k + 1));
if (tmp == NULL)
{
perror("malloc fail");
return NULL;
}
obj->a = tmp;
obj->front = obj->rear = 0;
obj->k = k;
return obj;
}
④循环队列插入数据
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
if (myCircularQueueIsFull(obj))
{
return false;
}
else
{
obj->a[obj->rear] = value;
obj->rear = (obj->rear + 1) % (obj->k + 1);
return true;
}
}
⑤循环队列弹出数据
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
if (myCircularQueueIsEmpty(obj))
{
return false;
}
else
{
obj->front = (obj->front + 1) % (obj->k + 1);
return true;
}
}
⑥取得队首元素
int myCircularQueueFront(MyCircularQueue* obj)
{
if (myCircularQueueIsEmpty(obj))
{
return -1;
}
else
{
return obj->a[obj->front];
}
}
⑦取得队尾元素
int myCircularQueueRear(MyCircularQueue* obj)
{
if (myCircularQueueIsEmpty(obj))
{
return -1;
}
else
{
obj->rear = (obj->rear + obj->k) % (obj->k + 1);
return obj->a[obj->rear];
}
}
⑧循环队列的销毁
void myCircularQueueFree(MyCircularQueue* obj)
{
free(obj->a);
free(obj);
}
3.循环队列的优势与劣势
①优势
-
节约空间:循环队列可以在数组的空间内实现队列的操作,不像普通队列那样需要使用链表来实现队列。这样就可以节省额外的内存空间。
-
操作效率高:在循环队列中,无论在队列头或者队列尾插入或删除元素的操作都可以在 O(1) 的时间复杂度内完成,因此循环队列在效率方面优于普通队列。
-
方便操作:由于循环队列是通过数组实现的,因此可以直接根据下标访问队列中的元素,这种方式对于一些特定应用场景非常方便。
②劣势
-
容量有限:循环队列的容量是固定的,如果队列已满,则无法再插入新的元素,这就限制了循环队列的使用场景。
-
不支持动态扩容:由于循环队列的容量是固定的,因此无法在队列已满的情况下扩展容量,这就导致了无法支持动态扩容的缺陷。
-
索引混乱问题:由于循环队列中的元素是循环存储的,如果不处理好循环的情况,可能会导致索引混乱的问题,增加程序的复杂度。