首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言靜態數組實現循環隊列:犧牲一單元區分滿空的經典技巧

     編輯:關於C

循環隊列核心思想

數組首尾相連形成邏輯環,head 指向隊頭元素,tail 指向下一個插入位置。當 tail+1 == capacity 時回繞到 0。

關鍵判斷條件

完整實現

#define QUEUE_CAP 100

typedef struct {
    int data[QUEUE_CAP];
    int head, tail;
} CircularQueue;

void Queue_Init(CircularQueue *q) { q->head = q->tail = 0; }

bool Queue_IsEmpty(const CircularQueue *q) { return q->head == q->tail; }
bool Queue_IsFull(const CircularQueue *q) { return (q->tail + 1) % QUEUE_CAP == q->head; }

bool EnQueue(CircularQueue *q, int val) {
    if (Queue_IsFull(q)) return false;
    q->data[q->tail] = val;
    q->tail = (q->tail + 1) % QUEUE_CAP;
    return true;
}

bool DeQueue(CircularQueue *q, int *out) {
    if (Queue_IsEmpty(q)) return false;
    *out = q->data[q->head];
    q->head = (q->head + 1) % QUEUE_CAP;
    return true;
}

void Queue_Print(const CircularQueue *q) {
    for (int i = q->head; i != q->tail; i = (i + 1) % QUEUE_CAP)
        printf("%d ", q->data[i]);
    puts("");
}

測試用例

int main(void) {
    CircularQueue q; Queue_Init(&q);
    EnQueue(&q, 4); EnQueue(&q, 1); EnQueue(&q, 2);
    EnQueue(&q, 9); EnQueue(&q, 8);
    Queue_Print(&q);      // 4 1 2 9 8
    int v;
    DeQueue(&q, &v); DeQueue(&q, &v);
    Queue_Print(&q);      // 2 9 8
    return 0;
}

進階:不犧牲單元的替代方案

  1. 計數器法:增加 size 字段,滿判斷 size == CAP,空 size == 0。
  2. 標志位法:增加 bool full_flag,入隊置 true,出隊置 false。
  3. 指針標記法:head/tail 用結構體帶 tag 位(需原子操作)。

犧牲一單元法最簡潔,嵌入式/教學首選;高性能庫常用計數器法。

避坑提醒

  • tail 指向下一個寫入位置,而非最後元素,勿混淆。
  • 打印/遍歷時用 i != tail 條件,而非 i < tail(跨越 0 界失效)。
  • 併發場景需對 head/tail/size 加鎖或用原子操作。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
狀態條件含義
空head == tail無有效元素
滿(tail + 1) % CAP == head犧牲一單元,實際容量 CAP-1