隊列作為先進先出(FIFO)的線性數據結構,在任務調度、緩衝區管理等場景中至關重要。本文提供基於鏈表的隊列完整實現,包含創建、入隊、出隊、銷毀等核心操作,代碼結構清晰,適合學習與項目直接使用。
採用帶頭結點的鏈表結構,隊列結構體維護隊首和隊尾指針,實現O(1)時間複雜度的入隊出隊操作:
typedef int ElementType; // 隊列元素類型,可根據需要修改
typedef struct QueueNode {
ElementType element;
struct QueueNode *next;
} QueueNode, *Node;
typedef struct {
Node first; // 隊首指針(指向頭結點)
Node last; // 隊尾指針(指向最後一個元素結點)
} QueueStruct, *Queue;
1. 創建空隊列
分配頭結點並初始化首尾指針均指向頭結點:
Queue createQueue() {
Queue Q = (Queue)malloc(sizeof(QueueStruct));
Node node = (Node)malloc(sizeof(QueueNode));
if (!Q || !node) {
fprintf(stderr, "內存分配失敗\n");
exit(EXIT_FAILURE);
}
node->next = NULL;
Q->first = Q->last = node;
return Q;
}
2. 判斷隊列是否為空
通過比較首尾指針是否相等判斷:
int isEmpty(Queue Q) {
return Q->first == Q->last;
}
3. 入隊操作
在隊尾插入新結點,更新隊尾指針:
void EnQueue(ElementType X, Queue Q) {
Node node = (Node)malloc(sizeof(QueueNode));
if (!node) {
fprintf(stderr, "內存分配失敗\n");
exit(EXIT_FAILURE);
}
node->element = X;
node->next = NULL;
Q->last->next = node;
Q->last = node;
}
4. 出隊操作
刪除隊首元素結點(頭結點之後的第一個結點),返回元素值:
ElementType DeQueue(Queue Q) {
if (isEmpty(Q)) {
fprintf(stderr, "隊列為空\n");
exit(EXIT_FAILURE);
}
Node p = Q->first->next;
ElementType x = p->element;
Q->first->next = p->next;
// 若刪除的是最後一個元素,需更新隊尾指針
if (p == Q->last) {
Q->last = Q->first;
}
free(p);
return x;
}
5. 銷毀隊列
循環出隊釋放所有元素結點,最後釋放頭結點和隊列結構體:
void deleteQueue(Queue Q) {
while (!isEmpty(Q)) {
DeQueue(Q);
}
free(Q->first); // 釋放頭結點
free(Q); // 釋放隊列結構體
}
#ifndef QUEUE_H #define QUEUE_H #include#include typedef int ElementType; typedef struct QueueNode *Node; typedef struct queue *Queue; struct QueueNode { ElementType element; Node next; }; struct queue { Node first; Node last; }; Queue createQueue(); int isEmpty(Queue Q); void EnQueue(ElementType X, Queue Q); ElementType DeQueue(Queue Q); void deleteQueue(Queue Q); #endif
以下主函數演示隊列基本操作:
int main() {
Queue q = createQueue();
printf("入隊 10, 20, 30...\n");
EnQueue(10, q);
EnQueue(20, q);
EnQueue(30, q);
printf("出隊順序: ");
while (!isEmpty(q)) {
printf("%d ", DeQueue(q));
}
printf("\n");
deleteQueue(q);
return 0;
}
輸出結果:入隊 10, 20, 30... 出隊順序: 10 20 30
ElementType宏定義元素類型,便於擴展為任意數據類型1. 線程安全:當前實現非線程安全,多線程環境需添加互斥鎖
2. 錯誤處理:生產環境建議將exit()改為返回錯誤碼,由調用者處理
3. 性能優化:高頻操作場景可考慮內存池減少malloc/free開銷
4. 功能擴展:可添加獲取隊首元素、獲取隊列長度等輔助功能
這個鏈式隊列實現結構清晰、操作高效,是理解隊列數據結構和C語言指針操作的優秀範例。掌握其核心邏輯後,可輕鬆擴展為循環隊列、雙端隊列等進階結構。