这是一道来自LeetCode的题目——https://leetcode.cn/problems/design-circular-queue/https://leetcode.cn/problems/design-circular-queue/
根据题意,我们可以思考出大概的模型。
很明显的看到这里需要记录队列头和队列尾,还需要得到的数据是队列大小——
要实现这个数据结构,可以用“链表”和“数组”两种方式存储数据。但是如果使用单链表实现环形队列,则会较为麻烦。
这是完成创建及基本操作(增、删、判空、判满)的基本思路——
typedef struct {
int* a;
int k;
int head;
int tail; //tail用来记录尾部数据下一个位置
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->a = (int* )malloc(sizeof(int) * (k + 1));
obj->head = obj->tail = 0;
obj->k = k;
return obj;
}
首先我们创建结构体,然后开辟空间用来存储数据
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->head == obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->tail+1)%(obj->k+1)==obj->head; //因为上方开了k+1个空间,若为(obj->tail)%(obj->k),
//则第k位置放不了数据,所以需要+1取模,确保第k位能放入
//或者直接记录尾结点加一的位置,将其与长度加一的空间进行比较,
//这里不用(obj->tail)==(obj->k)原理同上
}
接下来是判空和判满,判满这里可以用到取模的思想或者记录尾指针的思维。
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if (myCircularQueueIsFull(obj))
return false;
obj->a[obj->tail] = value;
obj->tail++;
if (obj->tail == obj->k + 1)
obj->tail = 0;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return false;
++obj->head;
if (obj->head == obj->k + 1)
obj->head = 0;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
return obj->a[obj->head];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
int pre = obj->tail - 1;
if (obj->tail == 0)
pre = obj->k;
return obj->a[pre];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->a = NULL;
obj->head = obj->tail = 0;
}
以上就是循环队列的基本功能实现。



