数据结构——队列(银行叫号系统)

一、实验目的

(1)掌握队列的链式存储结构

(2)掌握队列的基本操作,并能进行应用实践

(3)使用C/C++语言和队列实现”银行叫号系统“专题

二、实验任务

设计一个控制台程序,模拟银行排队业务,要求实现功能:

(1)输出程序界面,提示客户输入银行窗口数量和开放窗口时间

(2)客户随机时间进入银行,程序在事件表中记录客户进入时间和离开时间,并将客户排入窗口队列,办理完业务后退出队列
(3)窗口开放时间结束,客户停止进入银行,直到所有客户退出队列之后计算出客户的平均服务时间

三、实验代码

1.事件列表
1)定义事件结点

typedef struct Event//定义事件结点
{int occurTime;//发生时刻int type;//事件类型:0表示顾客到达;1~N表示顾客从N号窗口离开struct Event *next;
}Event,*EventList;

2)初始化事件链表

int InitList(EventList* pList)//初始化事件链表
{*pList=(Event*)malloc(sizeof(Event));if(*pList==NULL){printf("分配内存失败\n");exit(-1);}(*pList)->next=NULL;return OK;
}

3)插入元素

int OrderInsert(EventList pList,Event sEvent)//插入元素
{Event *pAfter,*pBefore;//临时变量,用于在链表中插入结点pAfter=pList;pBefore=pList->next;while(pAfter!=NULL && sEvent.occurTime>pAfter->occurTime)//比较事件发生的时间{pBefore=pAfter;pAfter=pAfter->next;}pBefore->next=(Event*)malloc(sizeof(Event));//创建一个新的结点,挂在Before和After两个结点中间pBefore->next->occurTime=sEvent.occurTime;//对新结点赋值pBefore->next->type=sEvent.type;pBefore->next->next=pAfter;return OK;
}

4)判断链表是否为空

int EmptyList(EventList pList)//判断链表是否为空
{if(pList->next==NULL)return TRUE;elsereturn FALSE;
}

5)删除首结点

int DelFirst(EventList pList,Event *pEvent)//删除首结点
{Event *pTmp;if(EmptyList(pList)){printf("链表为空");return ERROR;}else {pTmp=pList->next;//删除链表首结点pList->next=pTmp->next;*pEvent=*pTmp;//保存数值free(pTmp);//释放内存return OK;}
}

6)遍历链表

int ListTraverse(EventList pList)//遍历链表
{Event *pTmp;pTmp=pList;while(pTmp->next!=NULL){pTmp=pTmp->next;if(pTmp->type==0)printf("第%d分钟,下一名客户即将到来。\n",pTmp->occurTime);elseprintf("第%d分钟,%d号窗口的客户即将离开。\n",pTmp->occurTime,pTmp->type);}printf("\n");return OK;
}

2.链式队列
1)定义链式队列数据结构

typedef struct QElemType{//定义链式队列数据结构int arriveTime;//到达时间int duration;//持续时间struct QElemType *next;
}QElemType;
typedef struct LinkedQueue{QElemType *front;//头指针QElemType *rear;//尾指针
}LinkedQueue;

2)初始化队列

int InitQueue(LinkedQueue *pQueue)//初始化队列
{pQueue->front=pQueue->rear=(QElemType*)malloc(sizeof(QElemType));//分配内存if(pQueue->front==NULL){printf("分配内存失败\n");exit(-1);}pQueue->front->next=NULL;return OK;
}

3)判断链表是否为空

int EmptyQueue(LinkedQueue *pQueue)//判断链表是否为空
{if(pQueue->front==pQueue->rear)return TRUE;else return FALSE;
}

4)首结点出队

int DelQueue(LinkedQueue *pQueue,QElemType *pQElem)//首结点出队
{QElemType *pTmp;//临时结点指针if(EmptyQueue(pQueue)){printf("队列为空,不能继续出队列\n");return ERROR;}else {//指向首结点后一个元素,并复制给pQElempTmp=pQueue->front->next;*pQElem=*pTmp;pQueue->front->next=pTmp->next;//删除这个结点if(pQueue->rear==pTmp)pQueue->rear=pQueue->front;free(pTmp);return OK;}
}

5)结点入队

int EnQueue(LinkedQueue *pQueue,QElemType sQElem)//结点入队
{QElemType *pTmp;//临时结点指针pTmp=(QElemType*)malloc(sizeof(QElemType));if(pTmp==NULL){printf("内存分配失败\n");exit(-1);}else {//尾结点指向新入队的元素*pTmp=sQElem;pTmp->next=NULL;pQueue->rear->next=pTmp;pQueue->rear=pTmp;}return OK;
}

6)获取队列长度

int QueueLength(LinkedQueue *pQueue)//获取队列长度
{QElemType *pTmp;//临时结点指针int count=0;//遍历链表,统计结点数pTmp=pQueue->front->next;//队列第一个结点while(pTmp!=NULL){count++;pTmp=pTmp->next;}return count;
}

7)获取队列首结点

int GetHead(LinkedQueue *pQueue,QElemType *pQElem)//获取队列首结点
{if(EmptyQueue(pQueue)){printf("队列为空");return ERROR;}*pQElem=*(pQueue->front->next);return OK;
}

8)遍历队列

int QueueTraverse(LinkedQueue *pQueue)//遍历队列
{QElemType *pTmp;//临时结点指针if(EmptyQueue(pQueue)){printf("队列为空\n");return ERROR;}pTmp=pQueue->front->next;//队列第一个结点while(pTmp!=NULL){printf(">[到达时刻:第%d分钟,服务时长:%d分钟]\n",pTmp->arriveTime,pTmp->duration);pTmp=pTmp->next;}printf("\n");return OK;
}

3.主要业务功能
1)定义全局变量

#define MAXSIZE 20//银行服务窗口最大数量
int gWindowsNum;//银行服务窗口数
int gCustomerNum;//客户总人数
int gTotalTime;//总服务时间
int gCloseTime;//银行关闭时间
EventList gEventList;//事件列表
Event gEvent;//事件
LinkedQueue gQueue[MAXSIZE];//队列数组
QElemType gCustomer;//队列结点

2)初始化数据

void Initialize( )//初始化数据
{int i;gTotalTime=0;gCustomerNum=0;InitList(&gEventList);//初始化事件列表printf("请输入银行服务窗口个数(1~20):");//服务窗口个数scanf("%d",&gWindowsNum);while (gWindowsNum<1 || gWindowsNum>MAXSIZE){printf("请输入1到%d之间的整数:",MAXSIZE);scanf("%d",&gWindowsNum);}printf("\n请输入服务关闭时间(超过这个时间就不在接纳新顾客)(单位:分钟):");//服务关闭时间scanf("%d",&gCloseTime);while(gCloseTime<1){printf("请输入大于零的整数:");scanf("%d",&gCloseTime);}for(i=0;i<gWindowsNum;i++)//为每个窗口建立一个空队列{InitQueue(&gQueue[i]);}
}

3)处理客户到达事件

int ShortestQueue( );void CustomerArrived()//处理客户到达事件
{QElemType sQElem;Event sEvent;int index;//排队人数最少的窗口编号int arrivetime;//客户到达时间int duration;//业务办理时间printf("当前时刻:第%d分钟\n", gEvent.occurTime);//顾客到达的时间,在上一位顾客之后1~5分钟arrivetime = gEvent.occurTime+ rand() % 5 + 1;duration = rand() % 21 + 10;//办理业务时间为10~30分钟if (arrivetime < gCloseTime)//服务尚未关闭{gCustomerNum++;//新顾客到达事件sEvent.occurTime = arrivetime;sEvent.type = 0;OrderInsert(gEventList, sEvent);//顾客进入人数最少的窗口排队sQElem.arriveTime = gEvent.occurTime;//入队时刻sQElem.duration = duration;//办理业务时间index = ShortestQueue();EnQueue(&gQueue[index], sQElem);//入列//如果恰好排在了队首,预定离开事件if (QueueLength(&gQueue[index]) == 1){//记录顾客从第index+1号号窗口离开(因为索引从0开始)sEvent.occurTime =gEvent.occurTime + duration;sEvent.type = index + 1;OrderInsert(gEventList, sEvent);}}else//银行排队服务关闭,不再接受新客户printf("\n排队服务以关闭,不再接受新客户!\n");
}

4)处理顾客离开事件

void CustomerLeaved( )//处理顾客离开事件
{Event sEvent;int index=gEvent.type-1;//队列编号为窗口编号-1DelQueue(&gQueue[index],&gCustomer);//删除队首结点printf("\n顾客离开时间:第%d分钟。",gEvent.occurTime);gTotalTime+=gCustomer.duration;//记录服务时间//如果队列不为空,则预定下一位顾客从第index+1号窗口离开if(!EmptyQueue(&gQueue[index])){GetHead(&gQueue[index],&gCustomer);//获得下一位顾客//记录离开事件sEvent.occurTime=gEvent.occurTime+gCustomer.duration;sEvent.type=index+1;OrderInsert(gEventList,sEvent);}
}

5)获取最短队列的编号

int ShortestQueue( )//获取最短队列的编号
{int i=0;int min=9999;//最短队列的长度int index=-1;//最短队列的编号int length=0;//遍历各个窗口,比较哪个窗口排队的人最少for(i=0;i<gWindowsNum;i++){length=QueueLength(&gQueue[i]);if(min>length){min=length;index=i;}}return index;
}

6)显示当前窗口队列

void PrintQueue( )//显示当前窗口队列
{int i;printf("\n窗口排队状态:\n");for(i=0;i<gWindowsNum;i++){printf("%d号窗口:\n",i+1);QueueTraverse(&gQueue[i]);}printf("\n");
}

7)显示当前时间表

void PrintEventList( )//显示当前时间表
{printf("\n事件表状态:\n");ListTraverse(gEventList);
}

8)银行排队模拟

void BankSimulation( )//银行排队模拟
{//随机数发生器,用于模拟随机客户排队事件//根据当前系统时间初始化随机种子srand( (unsigned)time(NULL));//准备开业Initialize( );//第一个顾客到来gEvent.occurTime=0;gEvent.type=0;OrderInsert(gEventList,gEvent);//处理排队列表while(!EmptyList(gEventList)){DelFirst(gEventList,&gEvent);//处理顾客事件if(gEvent.type==0)CustomerArrived( );elseCustomerLeaved( );//显示当前事件列表,以及排队情况PrintEventList( );PrintQueue( );//暂停一会,便于观察输出内容system("PAUSE");printf("\n");}//平均服务时间printf("\n");printf("客户平均服务时间:%f分钟\n",(float)gTotalTime/gCustomerNum);system("PAUSE");
}

4.主函数入口

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<time.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -2
int main( )//主函数入口
{BankSimulation( );return 0;
}

5.程序运行截图


**~~本 蒟蒻 发布的第一篇文章,贴代码不易,复制后别忘了 点赞哦 (@W@)!,蟹蟹啦!*

数据结构——队列(银行叫号系统)相关推荐

  1. 数据结构实验二——队列(银行叫号系统)

    一.实验目的 (1)掌握队列的链式存储结构 (2)掌握队列的基本操作,并能进行应用实践 (3)使用C/C++语言和队列实现"银行叫号系统"专题 二.实验任务 设计一个控制台程序,模 ...

  2. 基于IDEA的JavaWeb银行叫号系统

    文档源资源见: https://pan.baidu.com/s/1Vc35QF-SP5NFq1xQJeX1jQ 提取码: 8259 复制这段内容后打开百度网盘手机App,操作更方便哦 基于JavaWe ...

  3. 用python写银行叫号系统(这个是学校的实训题目,真的没什么技术含量)

    一. 项目概述 智能排队叫号系统是在银行等待业务办理区域所使用的智能叫号系统,系统可有效解决客户办理业务时排队的无序.业务员工作量的不平衡.就诊环境嘈杂等问题. 二. 需求分析 主要分为取号.排队等待 ...

  4. java 银行叫号系统

    ---------------------- ASP.Net+Unity开发. .Net培训.期待与您交流! ---------------------- 项目需求:模拟实现银行业务调度系统逻辑,银行 ...

  5. 叫号系统排队系统挂号系统实现(JAVA队列)

    关于队列,使用的地方非常的多.现实中有很多的例子.比如医院的挂号系统,银行里的叫号系统,食堂里的排队打饭等等.市场上又这样的排队取号的设备.他们的功能基本如下: 1.系统可联网联机统一发号: 2.系统 ...

  6. 叫号系统排队系统挂号系统实现

    关于队列,使用的地方非常的多.现实中有很多的例子.比如医院的挂号系统,银行里的叫号系统,食堂里的排队打饭等等.市场上又这样的排队取号的设备.他们的功能基本如下: 1.系统可联网联机统一发号: 2.系统 ...

  7. 【叫号系统】Redis ZSet结构

    本文记录一下ZSet的使用心得,使用实例在[叫号系统]中,是一个简单的小系统. [叫号系统]:用户来到考试现场进行签到,签到成功的用户进入"等待队列". 考试科目分为:学科一.学科 ...

  8. 数据结构——数据结构模拟银行排号叫号系统参考

    数据结构模拟银行排号叫号系统参考 4/27.作业三 用队列的简单操作实现,代码较简单,提示信息易懂 定义一个结构体SqQueue 判断队列是否为空 判断队列是否已满 向队列中插入元素 元素e出队,并用 ...

  9. 模拟银行窗口排队叫号系统的运作

    最近在网上看到了一道面试题,初看很简单,细看有点意思的一道题目: http://blog.csdn.net/zhangxiaoxiang/archive/2011/04/01/6294132.aspx ...

  10. mfc 子窗体 按钮不触发_资深程序员用c++开发MFC银行排队叫号系统,小白看了也能学会...

    这个C++ 银行排队叫号系统是看了书后写出来的程序,运用于MFC理念编写,我看的书是谭浩强的<C++面向对象程序设计>相对计科的书少了前六章 直接从对象讲起,这本书也是本班使用人数最多的一 ...

最新文章

  1. 2022-2028年中国节能建材行业深度调研及投资前景预测报告
  2. 一个经典例子让你彻彻底底理解java回调机制
  3. .net 操作xml
  4. k8s部署oracle-ee-11g:部署、集群内外连接oracle的方式
  5. SmartTemplate学习入门一
  6. 一文带你了解数据中心大二层网络演进之路
  7. (转)关于两次fork
  8. python典型应用场景、domo及模板之一-----------配置日志
  9. 配置nginx,Tomcat日志记录请求耗时
  10. redis发布订阅者
  11. vs code调试console程序报错--preLaunchTask“build”
  12. Unity Shader-深度相关知识总结与效果实现(LinearDepth,Reverse Z,世界坐标重建,软粒子,高度雾,运动模糊,扫描线效果)
  13. 手机点餐系统概述_基于Android无线点餐系统的设计与实现
  14. 【JavaScript】JavaScript模拟实现面向对象一张图帮助你深刻理解原型链和原型对象
  15. 凌晨3点不回家,你不要老婆孩子了?
  16. js贝塞尔曲线cubic-bezier 模拟实现附UnitBezier.h
  17. 基于改进区域生长算法的PET-CT成像自动肺实质分割方法(笔记六)
  18. 斐讯音箱控制扫地机器人_斐讯商城教您,如何正确使用扫地机器人?
  19. QQ已经被恶意外挂破坏
  20. 安卓移除/忘记已保存的WiFi密码

热门文章

  1. 戴尔服务器2012系统密钥,戴尔恢复密钥在哪里找
  2. linux php adodb,【原创】Linux下php使用adodb对sql Server访问配置
  3. 【eoeAndroid社区索引】android开发混淆
  4. 曼联足球俱乐部披露安全漏洞
  5. 433MHz LoRa/FSK 无线频谱波形分析(频谱分析仪测试LoRa/FSK带宽、功率、频率误差等)
  6. java导论pdf下载,人工智能导论 PDF 下载
  7. 使用“网吧卫士”实现网吧带宽完美管理(转)
  8. 怎么更改win7登录界面 梦幻桌面动态效果电脑桌面快速分屏设置虚拟wifi热点方法_桌面图标弹出提示飞雪桌面日历自定义桌面
  9. 【word论文排版教程4】样式的应用
  10. android 直播 h5,H5移动端直播的要点