核心操作
原题链接
通过取模运算实现循环
实现思路:
创造循环队列时,实际长度要比有效长度多1。
为了让头尾指针能够在数组内循环起来,需要做取模处理。
想象成数组闭环,会更容易理解取模处理。
- 初始化
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//申请比k+1个空间,front指向有效数据的第一个节点,tail指向有效数据的下一个节点
//这里初始化front和tail为第一个节点
cq->a=(int*)malloc(sizeof(int)*(k+1));
cq->front=cq->tail=0;
cq->size=k;
return cq;
}
- 判空
当头指针和尾指针重合队列为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
if(obj->tail==obj->front) return true;
return false;
}
- 判满
如果尾指针再往后走一步指向头指针
bool myCircularQueueIsFull(MyCircularQueue* obj) {
if((obj->tail+1)%(obj->size+1)==obj->front) return true;
return false;
}
- 进队操作
判满,给尾节点赋值,尾节点向后移一位
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
//判满
if(myCircularQueueIsFull(obj)) return false;
obj->a[obj->tail]=value;
obj->tail=(obj->tail+1)%(obj->size+1);
return true;
}
- 出队操作
判空,头节点向后移一位
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
//判空
if(myCircularQueueIsEmpty(obj)) return false;
obj->front=(obj->front+1)%(obj->size+1);
return true;
}
}
- 获取队头元素
判空后获取头节点
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj)) return -1;
return obj->a[obj->front];
}
- 获取队尾元素
判空后获取尾节点前一个结点
int myCircularQueueRear(MyCircularQueue* obj) {
//判空
if(myCircularQueueIsEmpty(obj)) return -1;
return obj->a[(obj->tail+obj->size)%(obj->size+1)];
}
AC代码
typedef struct {
int* a;//开辟数组
int front;//头节点
int tail;//尾节点
int size;//当前队列存在元素个数
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);
//初始化
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* cq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//申请比k+1个空间,front指向有效数据的第一个节点,tail指向有效数据的下一个节点
//这里初始化front和tail为第一个节点
cq->a=(int*)malloc(sizeof(int)*(k+1));
cq->front=cq->tail=0;
cq->size=k;
return cq;
}
//进队
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
//判满
if(myCircularQueueIsFull(obj)) return false;
obj->a[obj->tail]=value;
obj->tail=(obj->tail+1)%(obj->size+1);
return true;
}
//出队
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
//判空
if(myCircularQueueIsEmpty(obj)) return false;
obj->front=(obj->front+1)%(obj->size+1);
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj)) return -1;
return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
//判空
if(myCircularQueueIsEmpty(obj)) return -1;
return obj->a[(obj->tail+obj->size)%(obj->size+1)];
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
if(obj->tail==obj->front) return true;
return false;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
if((obj->tail+1)%(obj->size+1)==obj->front) return true;
return false;
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
obj->tail=obj->front=obj->size=0;
free(obj);
}