银行普通/VIP客户双队列C语言实现:创建与入队出队传参问题
解决银行双队列(VIP/普通)的实现问题
我来帮你一步步解决这两个核心问题,同时修正代码里的错误,让你的双队列逻辑能正常跑起来:
问题1:如何在单个程序中创建两个队列?
你当前代码里重复定义了typedef struct queue,这在C语言里是不合法的——同一个typedef名称不能被重复声明。正确的做法是:
- 先定义一个通用的队列结构体,包含队列的队头(front)和队尾(rear)指针
- 然后创建这个结构体的两个实例:一个用于VIP客户,一个用于普通客户
这样既避免了重复定义的问题,又能清晰区分两个独立的队列。
问题2:如何将队列结构体作为入队/出队函数的参数?
因为入队和出队操作需要修改队列的front和rear指针(比如添加节点时要更新rear,删除节点时要更新front),所以必须传递队列结构体的指针给函数,而不是值传递(值传递会创建副本,修改副本不会影响原队列)。
接下来是修正后的完整实现,我会标注关键修改点:
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 定义链表节点结构体,存储客户信息 typedef struct Node { int record; int CardNum; char CustomerType[20]; struct Node* next; } Node; // 定义通用队列结构体:包含队头和队尾指针 typedef struct Queue { Node* front; Node* rear; } Queue; // 函数声明(修改参数为Queue指针) void Enqueue(Queue* queue, int record, int cardNum, const char* type); void Dequeue(Queue* queue); void ListQueue(Queue* queue, const char* queueName); int main() { // 创建两个队列实例:VIP队列和普通客户队列 Queue vipQueue = {NULL, NULL}; Queue ordinaryQueue = {NULL, NULL}; char command[10]; int record, cardNum; char type[20]; while (scanf("%s", command) != EOF) { if (strcmp(command, "IN") == 0) { printf("IN: 请输入记录号、卡号、客户类型(VIP/Ordinary): "); scanf("%d %d %s", &record, &cardNum, type); // 根据客户类型选择对应的队列入队 if (strcmp(type, "VIP") == 0) { Enqueue(&vipQueue, record, cardNum, type); printf("VIP客户已加入VIP队列\n"); } else if (strcmp(type, "Ordinary") == 0) { Enqueue(&ordinaryQueue, record, cardNum, type); printf("普通客户已加入普通队列\n"); } else { printf("无效的客户类型!请输入VIP或Ordinary\n"); } } else if (strcmp(command, "LIST") == 0) { printf("=== VIP队列 ===\n"); ListQueue(&vipQueue, "VIP"); printf("\n=== 普通队列 ===\n"); ListQueue(&ordinaryQueue, "普通"); printf("\n"); } else if (strcmp(command, "OUT") == 0) { // 银行常见逻辑:优先处理VIP队列,可根据需求调整 if (vipQueue.front != NULL) { printf("正在处理VIP客户:"); Dequeue(&vipQueue); } else if (ordinaryQueue.front != NULL) { printf("正在处理普通客户:"); Dequeue(&ordinaryQueue); } else { printf("所有队列为空,无客户可处理\n"); } } else if (strcmp(command, "QUIT") == 0) { printf("GOOD BYE!\n"); break; } else { printf("无效命令!请使用IN/LIST/OUT/QUIT\n"); } } // 可选:程序退出前释放队列内存,避免内存泄漏 // 可自行实现销毁队列的函数,遍历释放所有节点 return 0; } // 入队函数:接收队列指针,直接修改原队列 void Enqueue(Queue* queue, int record, int cardNum, const char* type) { // 创建新节点 Node* newNode = (Node*)malloc(sizeof(Node)); if (newNode == NULL) { printf("内存分配失败!\n"); return; } newNode->record = record; newNode->CardNum = cardNum; strcpy(newNode->CustomerType, type); newNode->next = NULL; // 如果队列为空,队头和队尾都指向新节点 if (queue->front == NULL) { queue->front = newNode; queue->rear = newNode; } else { // 否则,队尾节点的next指向新节点,更新队尾 queue->rear->next = newNode; queue->rear = newNode; } } // 出队函数:接收队列指针,直接修改原队列 void Dequeue(Queue* queue) { if (queue->front == NULL) { printf("队列为空!\n"); return; } // 保存队头节点,用于释放内存 Node* temp = queue->front; // 打印出队客户信息 printf("记录号:%d,卡号:%d,类型:%s\n", temp->record, temp->CardNum, temp->CustomerType); // 更新队头指针 queue->front = queue->front->next; // 如果队头变为NULL,说明队列已空,队尾也要置为NULL if (queue->front == NULL) { queue->rear = NULL; } // 释放节点内存 free(temp); } // 遍历打印队列函数 void ListQueue(Queue* queue, const char* queueName) { if (queue->front == NULL) { printf("%s队列为空\n", queueName); return; } Node* current = queue->front; while (current != NULL) { printf("记录号:%d,卡号:%d,类型:%s\n", current->record, current->CardNum, current->CustomerType); current = current->next; } }
关键修改点说明
队列结构体优化:
- 只定义了一个通用的
Queue结构体,避免重复typedef的错误 - 在
main中创建vipQueue和ordinaryQueue两个实例,分别对应两个队列
- 只定义了一个通用的
函数参数调整:
- 入队、出队、遍历函数都接收
Queue*(队列指针)作为参数,确保能直接修改原队列的front和rear指针 - 入队函数新增客户信息参数,符合实际业务逻辑
- 入队、出队、遍历函数都接收
业务逻辑完善:
- 出队时优先处理VIP队列(银行常见优先级逻辑,可按需修改)
- 增加了输入合法性检查,避免无效操作
- 补充了内存释放逻辑,防止内存泄漏
代码规范修正:
- 替换非标准的
malloc.h为标准的stdlib.h - 完善了提示信息,让交互更清晰
- 替换非标准的
内容的提问来源于stack exchange,提问作者Zuher Abud
相关产品推荐
相关产品推荐

