循环队列 (Circular Queue)

基于定长数组实现的环形缓冲区,头尾指针在数组内循环移动。enqueue/dequeue 均为 O(1)。


结构定义

typedef struct {
    int *data;
    size_t front;     /* 队头下标 */
    size_t rear;      /* 队尾下标(指向下一个空位) */
    size_t capacity;  /* 数组容量 */
    size_t size;      /* 当前元素数(也可通过 (rear - front + cap) % cap 推导) */
} CQueue;

函数签名

函数复杂度说明
void cq_init(CQueue *q, size_t cap)O(1)初始化,分配 cap 大小数组
int cq_enqueue(CQueue *q, int val)O(1)入队,满时返回 -1
int cq_dequeue(CQueue *q)O(1)出队,空时返回 -1(或未定义行为)
int cq_front(CQueue *q)O(1)查看队头
int cq_empty(CQueue *q)O(1)判空
int cq_full(CQueue *q)O(1)判满
void cq_free(CQueue *q)O(1)释放

核心实现

int cq_enqueue(CQueue *q, int val) {
    if (cq_full(q)) return -1;
    q->data[q->rear] = val;
    q->rear = (q->rear + 1) % q->capacity;
    q->size++;
    return 0;
}
 
int cq_dequeue(CQueue *q) {
    if (cq_empty(q)) return -1;
    int val = q->data[q->front];
    q->front = (q->front + 1) % q->capacity;
    q->size--;
    return val;
}

判空/判满策略

策略判空判满
牺牲一个槽位front == rear(rear + 1) % cap == front
额外 size 字段size == 0size == capacity
标志位empty == 1empty == 0 && front == rear

推荐使用 size 字段:逻辑清晰,额外存储可忽略。


典型应用

  • 消息队列(生产者-消费者模型)
  • BFS 广度优先搜索的待访问节点队列
  • 滑动窗口(TCP 接收缓冲区)
  • 键盘缓冲区

跨语言参考