隊列(Queue)作為「先進先出」(FIFO)的經典資料結構,天然契合銀行排隊、訂單處理、任務調度等業務場景。本文通過一個完整的銀行排隊叫號系統案例,演示如何在C語言中封裝循環隊列,並實現取號、叫號、查詢排隊人數等核心功能。
假設已有一個成熟的循環隊列介面seqQueue.h,提供以下核心操作:
SEQQUEUE *queue_init():初始化隊列int queue_push(SEQQUEUE *q, DATATYPE_T data):入隊(取號)DATATYPE_T *queue_pop(SEQQUEUE *q):出隊(叫號)int queue_empty(SEQQUEUE *q):判斷隊空int queue_full(SEQQUEUE *q):判斷隊滿int get_queue_length(SEQQUEUE *q):獲取當前排隊人數資料元素DATATYPE_T包含號碼與取號時間:
typedef struct {
int number; // 排隊號碼
time_t time; // 取號時間戳
} DATATYPE_T;
add_queue()int g_number = 0; // 全域變數:當前最大號碼
int add_queue(SEQQUEUE *queue) {
if (queue_full(queue)) {
printf("排隊人數已達上限,請稍後再試。\n");
return -1;
}
DATATYPE_T data;
data.number = ++g_number; // 號碼遞增
data.time = time(NULL); // 記錄當前時間
queue_push(queue, data); // 入隊
printf("取號成功,您的號碼是:%d\n", data.number);
return 0;
}
next()void next(SEQQUEUE *queue) {
if (queue_empty(queue)) {
printf("當前無排隊客戶。\n");
return;
}
DATATYPE_T *data = queue_pop(queue); // 出隊
printf("請 %d 號客戶到 %d 號窗口辦理業務。\n", data->number, 1); // 簡化窗口邏輯
}
int menu() {
printf("********************\n");
printf("1. 取號\n");
printf("2. 叫號\n");
printf("0. 退出系統\n");
printf("********************\n");
printf("請輸入選項: ");
return 0;
}
int main() {
SEQQUEUE *queue = queue_init();
if (!queue) {
printf("隊列初始化失敗!\n");
return -1;
}
int opt = 0;
do {
menu();
scanf("%d", &opt);
switch (opt) {
case 1:
add_queue(queue);
printf("當前等待人數: %d\n", get_queue_length(queue));
break;
case 2:
next(queue);
printf("當前等待人數: %d\n", get_queue_length(queue));
break;
case 0:
printf("系統已退出。\n");
break;
default:
printf("無效選項,請重新輸入。\n");
}
} while (opt != 0);
// 實際專案中應釋放隊列記憶體
return 0;
}
(rear+1)%maxSize == front判滿,front == rear判空,充分利用陣列空間。seqQueue.h/.c,主程式僅調用介面,降低耦合,便於維護與擴展(如改用鏈式隊列)。time.h記錄取號時間,可擴展統計平均等待時長等進階功能。這個案例展示了資料結構解決實際問題的威力。掌握隊列的封裝與應用,是C語言從「寫代碼」邁向「做工程」的關鍵一步。