如何用C语言通过记录最后操作判断循环队列的空满状态
用最后一次操作判断循环队列空满的C语言实现
要搞定这个判断逻辑,核心思路就是给你的队列结构体加个「状态标记」,专门记录上一次执行的是入队还是出队操作。咱们一步一步来改:
第一步:扩展队列结构体
首先,定义一个枚举类型表示操作类型,然后给QueueType加一个成员变量存这个状态(假设你的element是int,可根据实际需求修改):
#include <stdio.h> #include <stdlib.h> typedef int element; #define cQ_SIZE 5 // 定义操作类型枚举,区分初始、入队、出队状态 typedef enum { OP_INIT, // 队列初始化状态 OP_ENQUEUE, // 最后一次操作是入队 OP_DEQUEUE // 最后一次操作是出队 } OperationType; // 扩展后的循环队列结构体 typedef struct { int front; int rear; element queue[cQ_SIZE]; OperationType last_op; // 新增:记录最后一次操作类型 } QueueType;
第二步:初始化队列
别忘了初始化时把last_op设为OP_INIT,这是初始状态的特殊情况:
// 初始化循环队列 void initQueue(QueueType *cQ) { cQ->front = cQ->rear = 0; cQ->last_op = OP_INIT; }
第三步:实现空满判断函数
现在就能结合last_op和首尾指针的关系,精准判断空满了:
int isEmpty_lastOP(QueueType *cQ) { // 两种场景判定为空: // 1. 初始状态下首尾指针重合 // 2. 最后一次是出队操作,且首尾指针重合 if ((cQ->last_op == OP_INIT && cQ->front == cQ->rear) || (cQ->last_op == OP_DEQUEUE && cQ->front == cQ->rear)) { printf("Circular Queue is empty! "); return 1; } return 0; } int isFull_lastOP(QueueType *cQ) { // 只有一种场景判定为满: // 最后一次是入队操作,且首尾指针重合(初始状态重合不算满) if (cQ->last_op == OP_ENQUEUE && cQ->front == cQ->rear) { printf("Circular Queue is full! "); return 1; } return 0; }
第四步:修改入队出队函数,更新操作标记
每次执行入队或出队后,必须同步更新last_op的状态:
void enQueue_lastOP(QueueType *cQ, element item) { if (isFull_lastOP(cQ)) { printf("Enqueue failed: queue is full\n"); return; } cQ->rear = (cQ->rear + 1) % cQ_SIZE; cQ->queue[cQ->rear] = item; // 标记最后一次操作为入队 cQ->last_op = OP_ENQUEUE; } element deQueue_lastOP(QueueType *cQ) { if (isEmpty_lastOP(cQ)) { printf("Dequeue failed: queue is empty\n"); exit(1); } cQ->front = (cQ->front + 1) % cQ_SIZE; // 标记最后一次操作为出队 cQ->last_op = OP_DEQUEUE; return cQ->queue[cQ->front]; }
逻辑梳理
当front == rear时,结合最后一次操作就能准确区分空和满:
- 如果上一次是出队:说明是出队后首尾重合,队列已空
- 如果上一次是入队:说明是入队后首尾重合,队列已满
- 初始状态下首尾重合,属于队列空的情况
这样就完美实现了书中提到的第二种判断方法啦。
内容的提问来源于stack exchange,提问作者HJP DT
相关产品推荐
相关产品推荐

