由于设计的是一个固定的队列所以我们选择使用数组来实现,首先先定义一个结构体需要包含指向数组的指针、队头指针、队尾指针以及数组大小四个变量。数组种总是要有一个空位置这样子才可以分辨数组是否为空或满。
typedef struct {
int* _a;//由于不知道数组的大小所以先开一个指针来
int _real;//队尾
int _front;//对头
int _k;//数组大小
} MyCircularQueue;
初始化
设计好一个结构体以后第一件事就是要初始化将这个结构体初始化要将_a指针指向一个大小为k的数组并将队头和队尾指针指向数组的开始,并且将数组大小赋值
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
q->_a = (int*)malloc(sizeof(int) * (k + 1));//多开一个方便判断是否满和空
q->_front = 0;
q->_real = 0;
q->_k = k;
return q;
}
判断数组是否满了或者是否为空
先写好这两个函数方便后面入数据和删数据时可直接调用函数这两个函数比较简单只需返回对应的指针指向,当指针指向相同时数组为空返回1,指针指向不同数组不为空返回0;当尾指针+1指向的是头指针时数组满了返回1,不相等数组未满返回0(要注意越界问题,需要对尾指针磨一个数组长度加1)。
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->_front == obj->_real;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->_real + 1) % (obj->_k + 1) == obj->_front;
}
插入和删除
队列的函数接口的插入和删除是队列种比较重要的操作,在调用之后第一件事应该先判断是否满或者是否为空,在进行插入和删除操作,
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if (myCircularQueueIsFull(obj))
return false;
obj->_a[obj->_real] = value;
++obj->_real;
obj->_real %= (obj->_k + 1);//避免越界
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return false;
++obj->_front;
obj->_front %= (obj->_k + 1);//避免越界
return true;
}
返回队头的值和队尾的值
在这里依然需要调用是否满或者是否为空这个接口来判断能否返回正确的值否则返回-1;
int myCircularQueueFront(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
return obj->_a[obj->_front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
{
return -1;
}
else
{
return obj->_a[(obj->_real - 1 + obj->_k + 1) % (obj->_k + 1)];//避免越界
}
}
释放空间
这里需要注意释放空间时要先释放数组的空间再释放结构体变量。
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->_a);
free(obj);
}