news 2026/10/31 7:15:01

银行排队系统作业全解析:队列实现、多窗口调度与高分技巧

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
银行排队系统作业全解析:队列实现、多窗口调度与高分技巧

简介:这份数据结构期末作业资源面向计算机专业学生与C++初学者,围绕队列这一先进先出结构,实现带VIP优先级的银行排队模拟系统,帮助读者把课堂上的队列知识落到可运行的项目中。压缩包共9个文件、约1.03MB,以cpp源码、txt数据文件、cbp工程配置及exe可执行文件为主,另含编译中间产物与项目布局文件,构成一个可直接打开调试的Code::Blocks工程。已有3369人学习下载,说明其作为课程作业参考具有一定认可度。读者可从中获得双队列优先级调度的完整实现思路、用户信息文件的读取与解析方式、STL queue容器的实际用法,以及从源码到可执行程序的工程组织范例,便于对照理解控制流程与多队列设计,并在此基础上改写扩展。

1. 银行排队系统这道作业题,考的是你会不会用队列把业务流跑通

银行排队系统是数据结构期末作业里出现频率极高的一道综合题,表面看是"模拟叫号",实际考的是你对队列的完整掌握:顺序队列入队出队、循环队列判空判满、多窗口调度、以及队列和链表的取舍。很多人一上来就写界面,结果核心逻辑跑不通,分数直接腰斩。这类题通常占期末作业 20%~30% 的分值,评分点集中在"队列结构定义是否正确、入队出队边界是否处理、多窗口是否公平调度、统计指标是否算对"四块。适合正在赶期末作业、或者想把这题吃透拿去应对课程设计答辩的人。下面按考点分布、高频实现、真题演练、易错点、答题模板的顺序拆开讲,照着练就能把这道题从"能跑"做到"能拿高分"。

2. 考点分布:队列结构定义与基本操作是拿分底盘

2.1 顺序队列、循环队列、链队列怎么选

银行排队系统的底层就是一个队列,但队列有三种常见实现,选错实现方式会在判空判满上翻车。顺序队列用数组加两个指针,问题是"假溢出"——队头出队后前面空出来,队尾却顶到数组末尾,明明还有空间却报满。循环队列把数组首尾接起来,用(rear + 1) % MAXSIZE == front判满,牺牲一个存储单元换判满的简洁。链队列用带头结点的单链表,入队尾插、出队头删,不存在溢出问题,但每次出队要释放结点。

这道作业题里,如果题目明确要求"固定窗口数、顾客数已知",循环队列是标准答案;如果要求"顾客随时到达、数量不定",链队列更稳。面试官或评卷人最想看到的是你能说清为什么选它,而不是背定义。

实现方式判空条件判满条件适用场景
顺序队列front == rearrear == MAXSIZE不推荐,有假溢出
循环队列front == rear(rear+1)%MAXSIZE == front顾客数有上限
链队列front == rear(带头结点)无需判满顾客数不定

提示:循环队列判满牺牲一个单元是常规做法,如果题目要求"不浪费空间",可以加一个 count 计数器记录元素个数,判满改成count == MAXSIZE,答辩时主动提这一点是加分项。

2.2 入队出队边界:三个必须写对的判断

基本操作看着简单,但边界处理是评分重灾区。入队前必须判满,出队前必须判空,取队头前必须判空。循环队列的入队是rear = (rear + 1) % MAXSIZE; data[rear] = x;,出队是front = (front + 1) % MAXSIZE; x = data[front];,顺序不能反。链队列出队时要判断"是不是最后一个结点",如果是,出队后要把 rear 重新指向头结点,否则 rear 变成野指针。

// 循环队列入队,返回 1 成功 0 失败 int enqueue(CircularQueue *q, Customer c) { if ((q->rear + 1) % MAXSIZE == q->front) { return 0; // 队满,拒绝入队 } q->rear = (q->rear + 1) % MAXSIZE; q->data[q->rear] = c; // 先移指针再存数据 return 1; } // 循环队列出队 int dequeue(CircularQueue *q, Customer *c) { if (q->front == q->rear) { return 0; // 队空,无法出队 } q->front = (q->front + 1) % MAXSIZE; *c = q->data[q->front]; // 先移指针再取数据 return 1; }

这段代码的关键在"先移指针再存取"的顺序,和普通数组的data[rear++] = x不一样。参数MAXSIZE是队列容量,实际可用容量是MAXSIZE - 1。如果入队返回 0,调用方要处理"顾客被拒"的情况,很多作业直接忽略返回值,导致队满时数据被覆盖,这是典型的失分点。

2.3 多窗口调度:队列怎么分配给窗口

银行排队系统的核心难点不是单个队列,而是"多个窗口怎么从队列里取顾客"。常见有两种模型:一是所有顾客排一个大队,哪个窗口空了就从队头取一个,这叫单队列多服务台,公平性最好;二是每个窗口各有一个队列,顾客进队时选最短的队,这叫多队列多服务台,实现简单但可能出现"某队很长、某窗口却闲着"的不均衡。

期末作业里,如果题目写"顾客取号后排成一队,叫号系统按窗口空闲分配",就是单队列模型,用一个队列加一个窗口状态数组即可。如果写"顾客自行选择窗口排队",就是多队列模型,需要数组的队列。评卷时看的是你有没有把"窗口空闲判断"和"出队时机"写对——窗口服务时间到了才出队,而不是每个时间单位都出队。

// 单队列多窗口:每个时间单位检查各窗口是否空闲 for (int t = 0; t < TOTAL_TIME; t++) { for (int w = 0; w < WINDOW_NUM; w++) { if (windows[w].busy_time > 0) { windows[w].busy_time--; // 窗口正在服务,时间递减 } if (windows[w].busy_time == 0 && !is_empty(&queue)) { Customer c; dequeue(&queue, &c); // 窗口空闲,叫下一个 windows[w].busy_time = c.service_time; windows[w].served_count++; // 统计该窗口服务人数 } } }

这段循环是整个模拟的骨架。busy_time记录窗口剩余服务时间,减到 0 表示空闲,此时才从队列取人。served_count用于最后统计各窗口工作量。常见错误是把出队写在时间递减之前,导致窗口还没空就又叫了一个人,服务时间被覆盖。

3. 高频考点:时间模拟、统计指标与链表应用

3.1 离散时间模拟:顾客到达和服务怎么推进

银行排队系统本质是一个离散事件模拟,时间以"分钟"或"时间单位"为步长推进。每个时间单位要做三件事:新顾客按到达概率或到达表入队、各窗口服务时间递减、空闲窗口出队叫号。顾客的到达可以按固定间隔(每 2 分钟来一个),也可以按随机数(用rand()判断是否到达),题目一般会给定到达规则。

这里的高频考点是"到达和服务的时间关系"。如果顾客到达时所有窗口都忙,他必须留在队列里等待,等待时间 = 开始服务时间 - 到达时间。如果队列也满了(循环队列容量有限),顾客被拒,要统计拒绝人数。很多作业只算了服务时间,漏了等待时间,而等待时间恰恰是评价系统性能的核心指标。

// 顾客结构体:记录到达时间、服务时长、等待时长 typedef struct { int arrive_time; // 到达时刻 int service_time; // 需要服务时长 int wait_time; // 排队等待时长 } Customer; // 出队叫号时计算等待时间 c.wait_time = current_time - c.arrive_time; total_wait += c.wait_time;

wait_time在出队那一刻才能算,因为只有开始服务才知道等了多久。total_wait累加后除以服务总人数就是平均等待时间。这个指标几乎每份作业都要输出,算错直接丢分。

3.2 统计指标:平均等待、最大队长、窗口利用率

期末作业的评分表里通常有一栏"结果分析",要求输出至少三个统计量:平均等待时间、最大队列长度、各窗口服务人数或利用率。平均等待时间 = 总等待时间 / 总服务人数;最大队列长度在每次入队后更新max_len = max(max_len, queue_length);窗口利用率 = 窗口忙碌时间 / 总模拟时间。

这些指标不难,难在"统计时机"。最大队长要在入队之后立刻比较,而不是模拟结束才看;窗口忙碌时间要在服务期间累加,而不是只数服务人数。面试官问"你的系统性能怎么样",答的就是这几个数,所以作业里把它们算准,答辩时才有话可说。

3.3 链表在排队系统里的真实用途

除了队列本身,链表在这道题里还有两个常见用途:一是顾客记录链表,把所有服务过的顾客串起来,方便最后遍历输出每个人的到达、等待、离开时间;二是事件链表,按时间顺序存储"到达事件"和"离开事件",做真正的离散事件模拟(事件驱动法)。

事件驱动法是高分做法:不按固定时间步长循环,而是每次取出最早发生的事件处理,时间直接跳到该事件时刻。这样模拟效率高,也更能体现你对"优先队列/有序链表"的理解。如果作业允许自由发挥,用有序链表存事件、每次取最小时间事件,是拉开差距的地方。

// 事件结点:按发生时间有序插入链表 typedef struct EventNode { int time; // 事件发生时刻 int type; // 0 到达 1 离开 struct EventNode *next; } EventNode; // 有序插入:保证链表按 time 升序 void insert_event(EventNode **head, EventNode *e) { while (*head && (*head)->time <= e->time) { head = &(*head)->next; } e->next = *head; *head = e; }

有序插入的关键是二级指针head的移动,它让插入点自然落在第一个时间更大的结点之前。这样每次取事件只需取链表头,时间复杂度 O(1),插入 O(n)。参数type区分到达和离开,处理到达事件时生成新的离开事件插入链表,形成事件循环。

4. 真题演练:三道典型作业题的标准答法

4.1 题目一:用循环队列实现单窗口叫号

题目描述:银行只有一个窗口,顾客按到达顺序排队,实现入队、出队、查询队头、统计队列长度四个操作,队列容量为 10。

答题思路:先定义循环队列结构体,包含data数组、front、rear。四个操作分别对应enqueue、dequeue、get_front、get_length。get_length用(rear - front + MAXSIZE) % MAXSIZE计算,这是循环队列长度公式,很多人写成rear - front导致负数。

int get_length(CircularQueue *q) { return (q->rear - q->front + MAXSIZE) % MAXSIZE; }

加MAXSIZE是为了处理 rear 在 front 前面的情况,取模后得到正确长度。这道题面试官最想听的是你能解释"为什么长度不能直接相减",答出假溢出和指针回绕就到位了。

4.2 题目二:多窗口模拟并输出平均等待时间

题目描述:3 个窗口,顾客按每 2 分钟到达一个,服务时间随机 1~5 分钟,模拟 60 分钟,输出平均等待时间和各窗口服务人数。

答题思路:用单队列存顾客,窗口数组存忙碌状态。主循环按分钟推进,每到偶数分钟生成一个顾客入队,然后遍历窗口递减服务时间、空闲则出队。出队时算等待时间累加。最后输出total_wait / served_total和每个窗口的served_count。

这道题的坑在"模拟结束队列里还有人的情况"。60 分钟到了,队列里可能还有没服务完的顾客,严格来说要继续模拟直到队列清空,否则平均等待时间偏小。答题时主动说明"模拟时间结束后继续处理剩余顾客",是体现严谨性的细节。

4.3 题目三:用链队列实现不限人数的排队

题目描述:顾客人数不定,要求排队系统不设上限,实现入队、出队,并支持遍历输出所有顾客信息。

答题思路:用带头结点的链队列,front指向头结点,rear指向最后一个结点。入队尾插并更新 rear,出队头删,若删的是最后一个结点则 rear 回指头结点。遍历从头结点的下一个开始。

// 链队列出队,注意最后一个结点的处理 int dequeue(LinkQueue *q, Customer *c) { if (q->front == q->rear) return 0; // 空队列 QueueNode *p = q->front->next; *c = p->data; q->front->next = p->next; if (q->rear == p) { // 删的是最后一个结点 q->rear = q->front; // rear 回指头结点 } free(p); return 1; }

if (q->rear == p)这个判断是链队列最容易漏的一行,漏了之后 rear 指向已释放内存,下次入队就崩。面试官看到这行就知道你真写过链队列,不是抄的。

5. 易错点:五个让作业从 90 掉到 60 的坑

5.1 循环队列判满条件写错

错在哪:把判满写成rear == front,和判空条件一样,队列永远显示满或永远显示空。为什么错:循环队列里 front 和 rear 相等既可能是空也可能是满,必须用"牺牲一个单元"或"加计数器"区分。怎么答对:判空front == rear,判满(rear + 1) % MAXSIZE == front,并在注释里写明"牺牲一个单元"。

5.2 出队前不判空导致越界

错在哪:直接front = (front + 1) % MAXSIZE然后取数据,队列空时取到脏数据或越界。为什么错:空队列时 front 和 rear 相等,移动 front 后指向的是无效位置。怎么答对:出队函数第一行判空,返回失败码,调用方检查返回值再使用数据。

5.3 多窗口模拟出队时机错误

错在哪:每个时间单位对每个窗口都执行一次出队,不管窗口是否在忙。为什么错:窗口服务没结束就叫下一个人,前一个顾客的服务时间被覆盖,统计全乱。怎么答对:先递减busy_time,减到 0 才出队,出队后立刻设置新的busy_time。

5.4 平均等待时间分母用错

错在哪:用总人数做分母,包括被拒绝的顾客。为什么错:被拒顾客没有等待时间,算进去会拉低平均值。怎么答对:分母用"实际服务人数",被拒人数单独统计输出。

5.5 链队列出队不处理尾指针

错在哪:出队只改front->next,不管 rear。为什么错:删到最后一个结点时 rear 变成悬空指针,后续入队写入已释放内存。怎么答对:出队后判断rear == 被删结点,成立则rear = front。

6. 答题模板:从结构定义到结果分析的固定套路

6.1 代码结构按"定义—初始化—操作—模拟—输出"五段写

期末作业评分很看重结构清晰,建议固定五段式:第一段定义结构体(Customer、Queue、Window),第二段写初始化函数,第三段写队列基本操作,第四段写模拟主循环,第五段写统计输出。每段之间用注释分隔,评卷人一眼能找到得分点。主函数只负责调用,不写业务逻辑,这样即使某段有 bug,其他段的分数也能保住。

6.2 答辩时主动讲三个"为什么"

老师或面试官问得最多的不是"你怎么写的",而是"你为什么这么写"。提前准备三个答案:为什么选循环队列而不是链队列(固定容量、判满简单、缓存友好);为什么用单队列多窗口而不是多队列(公平、不会出现窗口闲置);为什么等待时间在出队时算(只有开始服务才知道等了多久)。这三个问题答顺了,答辩基本稳。

6.3 结果分析用表格呈现

最后输出别只打印几行数字,用表格把"总人数、服务人数、拒绝人数、平均等待、最大队长、各窗口服务数"列出来,再配一句结论,比如"窗口 2 服务人数最多,说明分配基本均衡"。评卷人看到有分析、有结论,印象分直接上去。

指标数值说明
总到达人数3060 分钟内每 2 分钟一个
实际服务人数282 人被拒
平均等待时间3.5 分钟总等待 / 服务人数
最大队列长度6入队后实时更新
窗口 1/2/3 服务数9/10/9分配较均衡

6.4 押题方向:事件驱动模拟和优先队列

如果这份作业还有拓展题或课程设计答辩,大概率会问"如果顾客有优先级(VIP 优先)怎么改"。答案是把普通队列换成优先队列,用堆或有序链表实现,按优先级出队。再进一步问"如果窗口服务时间不同怎么调度",答"按最早空闲窗口分配",本质是维护一个窗口空闲时间的最小堆。这两个方向提前想清楚,答辩时被追问也不慌。

我当年做这道作业,第一版循环队列判满写错,模拟跑出来队列永远是满的,调了一晚上才定位到那一行取模。从那以后我每次写循环队列,都先把判空判满两个条件写在纸上对照一遍再敲代码。希望这份拆解帮到你,把这道题的分稳稳拿住。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 7:14:18

云上大数据实验:Hadoop集群搭建与Spark SQL查询

简介&#xff1a;《华为云大数据实验报告hhu》面向高校大数据课程学习者与华为云入门实践者&#xff0c;围绕云上大数据平台的部署与管理给出四组实验记录。内容从弹性云服务器ECS与对象存储OBS的环境准备切入&#xff0c;覆盖Hadoop集群搭建、节点SSH互通、关闭防火墙与OpenJD…

作者头像 李华
网站建设 2026/10/31 7:13:55

Hadoop集群搭建排错:JAVA_HOME、SSH互信与OBS接入避坑

简介&#xff1a;《鲲鹏云大数据实验docx》是一份面向大数据初学者、云计算实验课程学生及需要完成华为云Hadoop集群部署实践者的实验报告。文档围绕鲲鹏云环境下的完整建链过程展开&#xff0c;涵盖ECS与OBS购买配置、AK/SK获取、节点互信与SSH免密、Hadoop安装包分发、core-s…

作者头像 李华
网站建设 2026/10/31 7:13:20

图形学作业0虚拟机环境排错:从挂载、增强功能到编译运行

简介&#xff1a;这份PDF文档对应GAMES101计算机图形学课程作业0&#xff0c;由闫令琪授课&#xff0c;面向刚接触图形学编程、需要搭建统一开发环境的学习者&#xff0c;重点解决虚拟机配置与作业框架运行的环境准备问题。全文围绕VirtualBox安装、虚拟硬盘挂载、Guest Additi…

作者头像 李华
网站建设 2026/10/31 7:13:18

UML系统分析与设计复习指南:多重度、交互图与GRASP高频考点

简介&#xff1a;面向备考UML系统分析与设计课程的学生及刚接触面向对象建模的开发者&#xff0c;这份复习试题文档围绕统一建模语言在系统分析与设计中的应用组织内容&#xff0c;可用于课程复习、考前自测与知识点查漏补缺。压缩包共1个doc文件&#xff0c;约132KB&#xff0…

作者头像 李华
网站建设 2026/10/31 7:10:25

ThingsBoard Gateway接入OPC-UA实战:从节点映射到可查可告警数据

简介&#xff1a;本资源是一份面向工业物联网开发者与自动化工程师的实操型技术文档&#xff0c;聚焦ThingsBoard Gateway与OPC-UA协议的端到端集成方案&#xff0c;解决工业现场设备如何安全、跨平台接入云端平台的核心问题。文档以KEPServerEX6模拟OPC-UA服务端、UaExpert作为…

作者头像 李华