推荐循环队列底层数组结构为数组:
思路:
如何判断队列是满的还是空的?
代码:
//定义循环队列的结构
typedef struct {
//指向循环队列的指针
int* arr;
//队列头已经队列尾
int front;
int read;
//循环队列空间的大小
int capacity;
} MyCircularQueue;
//循环队列的初始化
MyCircularQueue* myCircularQueueCreate(int k) {
//申请指向循环队列的指针
MyCircularQueue* ptr = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//申请循环队列的空间大小
ptr->arr = (int*)malloc(sizeof(int)*(k+1));
//让对头和队尾的位置都指向下标0
ptr->front = ptr->read = 0;
//循环队列的空间大小
ptr->capacity = k;
return ptr;
}
//入队列
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
//判断队列是否已经满了
if((obj->read+1)%(obj->capacity+1) == obj->front)
{
//如果队列满了,直接反正假
return false;
}
//插入数据,往数组的read下标插入,插入完成要read自增
*(obj->arr+obj->read++) = value;
obj->read %= obj->capacity+1;
//返回真
return true;
}
//循环队列中删除一个元素
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
//判断队列是否为空
if(obj->read == obj->front)
{
return false;
}
obj->front++;
obj->front %= obj->capacity+1;
return true;
}
//获取队首元素
int myCircularQueueFront(MyCircularQueue* obj) {
if(obj->read == obj->front)
return -1;
return *(obj->arr+obj->front);
}
//获取队尾元素
int myCircularQueueRear(MyCircularQueue* obj) {
if(obj->read == obj->front)
return -1;
//定义临时变量,保存read的前一个数据,但是要处理read在0这个下标的情况,减一的话就成-1了
//如果obj不是0的话就直接返回prev位置的数据,如果是0,先让prev走到队尾,然后返回队尾的数据
//因为当循环队列满的时候read是在下标为0的位置,此时取read-1的位置会越界,所以要回到队尾
int prev = obj->read - 1;
if(obj->read == 0)
prev = obj->capacity;
return *(obj->arr+prev);
}
//判断循环队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
//read和front相等的时候就说明队列为空
return obj->read == obj->front;
}
//判断队列是否已满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->read+1)%(obj->capacity+1) == obj->front;
}
//销毁循环队列
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->arr);
obj->arr = NULL;
obj->front = obj->read = obj->capacity = 0;
free(obj);
obj = NULL;
}
/**
* Your MyCircularQueue struct will be instantiated and called as such:
* MyCircularQueue* obj = myCircularQueueCreate(k);
* bool param_1 = myCircularQueueEnQueue(obj, value);
* bool param_2 = myCircularQueueDeQueue(obj);
* int param_3 = myCircularQueueFront(obj);
* int param_4 = myCircularQueueRear(obj);
* bool param_5 = myCircularQueueIsEmpty(obj);
* bool param_6 = myCircularQueueIsFull(obj);
* myCircularQueueFree(obj);
*/
提交结果:
循环队列的概念与结构:
实际中还有一种特殊的队列叫循环队列,环形队列首尾相连成环,环形队列可以使用数组实现,也可以使用循环链表实现。
队列满的情况下,为什么 Q.rear 不存储数据?
为了能使用 Q.rear = Q.front 来区别是队空还是队满,我们常常认为出现左图时的情况即为队满的情况。
此时:rear+1=front