You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

银行普通/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;
    }
}

关键修改点说明

  1. 队列结构体优化:

    • 只定义了一个通用的Queue结构体,避免重复typedef的错误
    • 在main中创建vipQueue和ordinaryQueue两个实例,分别对应两个队列
  2. 函数参数调整:

    • 入队、出队、遍历函数都接收Queue*(队列指针)作为参数,确保能直接修改原队列的front和rear指针
    • 入队函数新增客户信息参数,符合实际业务逻辑
  3. 业务逻辑完善:

    • 出队时优先处理VIP队列(银行常见优先级逻辑,可按需修改)
    • 增加了输入合法性检查,避免无效操作
    • 补充了内存释放逻辑,防止内存泄漏
  4. 代码规范修正:

    • 替换非标准的malloc.h为标准的stdlib.h
    • 完善了提示信息,让交互更清晰

内容的提问来源于stack exchange,提问作者Zuher Abud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:51:42