使用固定大小數組模擬循環隊列,通過 Front (隊頭)、Rear (隊尾)、Size (當前元素數) 三個索引管理,實現 O(1) 入隊/出隊。
#define MinQueueSize 5
struct QueueRecord {
int Capacity; // 數組容量
int Front; // 隊頭索引
int Rear; // 隊尾索引
int Size; // 當前元素數
int *Array; // 動態分配的數組
};
typedef struct QueueRecord *Queue;
Queue CreateQueue(int capacity) {
if (capacity < MinQueueSize) { /* 錯誤處理 */ return NULL; }
Queue Q = malloc(sizeof(struct QueueRecord));
Q->Array = malloc(capacity * sizeof(int));
Q->Capacity = capacity;
Q->Size = 0;
Q->Front = 0;
Q->Rear = -1; // 空隊列約定
return Q;
}
int IsEmpty(Queue Q) { return Q->Size == 0; }
int IsFull(Queue Q) { return Q->Size == Q->Capacity; }
void Enqueue(Queue Q, int x) {
if (IsFull(Q)) { /* 錯誤:隊列滿 */ return; }
Q->Rear = (Q->Rear + 1) % Q->Capacity; // 循環遞增
Q->Array[Q->Rear] = x;
Q->Size++;
}
void Dequeue(Queue Q) {
if (IsEmpty(Q)) { /* 錯誤:隊列空 */ return; }
Q->Front = (Q->Front + 1) % Q->Capacity; // 循環遞增
Q->Size--;
}
int Front(Queue Q) {
if (IsEmpty(Q)) { /* 錯誤 */ return -1; }
return Q->Array[Q->Front];
}
void ShowQueue(Queue Q) {
if (IsEmpty(Q)) { printf("Empty\n"); return; }
int i = Q->Front;
int count = 0;
while (count < Q->Size) {
printf("%d ", Q->Array[i]);
i = (i + 1) % Q->Capacity;
count++;
}
printf("\n");
}
int main(void) {
Queue Q = CreateQueue(10);
Enqueue(Q, 1); Enqueue(Q, 2); Enqueue(Q, 3);
Enqueue(Q, 4); Enqueue(Q, 5); Enqueue(Q, 6);
Dequeue(Q); // 移除 1
Enqueue(Q, 12); // 入隊 12
ShowQueue(Q); // 預期: 2 3 4 5 6 12
return 0;
}
if (Q->Rear == capacity) Q->Rear = 0; 僅在滿時觸發,且 capacity 越界。正確做法是每次入隊/出隊均用取模運算。Size < capacity 表示“未滿”,命名語義不清。改為 Size == Capacity。Front <= Rear 線性遍歷,循環隊列不成立。需按 Size 次循環取模訪問。DisposeQueue 釋放 Array 和 QueueRecord。循環隊列核心在於取模運算統一索引遞增邏輯,配合 Size 字段輕鬆區分“滿/空”狀態,避免犧牲一個存儲單元作區分標記。