logo资料库

银行排队模拟 C语言.doc

第1页 / 共10页
第2页 / 共10页
第3页 / 共10页
第4页 / 共10页
第5页 / 共10页
第6页 / 共10页
第7页 / 共10页
第8页 / 共10页
资料共10页,剩余部分请下载后查看
数据结构课程设计报告 题目:银行业务活动的模拟 学生姓名:赖锡宏 学 号:1021112513 班 级: 10211125 指导教师:高永平 2012 年 6 月 15 日
计算机与信息技术学院综合性、设计性实验报告 数据结构 专业:计算机科学与技术 年级/班级: 课程名称 本组成员 学号姓名 实验地点 项目名称 银行业务模拟系统的设计与实现 指导教师 实验时间 实验类型 综合性/设计性 一、实验目的 1)通过实验掌握对离散事件模拟的认识; 2)进一步理解队列的实现与应用; 3)对链表的操作有更深层次的理解; 该实验涉及到线性表的建立、插入、删除等操作,涉及到了队列的建立、插 入、删除,涉及到了离散事件的应用思想,还涉及到了排序的概念。完成这个实 验对线性表、队列及 C 语言编程等多方面的知识将是一个很好的利用,对离散事 件也将有一个初步的认识。 二、实验仪器或设备 1 台/学生微型计算机。 三、总体设计(设计原理、设计方案及流程等) 1.设计原理: 为了计算平均时间,就要掌握每个客户到达银行和离开银行这两个时 刻,后者减去前者即为每个客户在银行逗留的时间。所有客户逗留时间的 总和被一天内进入银行的客户数除便是所求的平均时间。 事件的主要信息是事件类型和事件发生的时刻,算法中要处理的事件 有两类:一类是客户到达的时间,另一类是客户离开的时间。前一类事件 发生的时刻随客户到来自然形成,后一类事件发生时刻则由客户事务所需 时间 和等待所耗时间而定。由于驱动程序是按时间发生时刻的先后顺序 进行,则事件表应该是有序表,其主要操作是插入和删除事件。 2.设计方案及流程 由于在实际的银行中,客户到达的时刻及其办理事务所需时间都是随 机的,在模拟程序中可用随机数代替,不失一般性。假设第一个客户进门 的时刻为 0,即是模拟程序处理的第一个事件,之后每个客户到达的时刻 在前一个客户到达时设定。因此在客户到达事件发生时需先产生两个随机 数:其一为此时刻到达的客户办理事务所需时间 durtime;其二为下一个 客 户 将 到 达 的 时 间 间 隔 intertime , 假 设 当 前 事 件 发 生 的 时 刻 为 occurtime,则下一个客户到达事件发生的时刻为 occurtime+intertime。 由此应产生一个新的客户到达时间插入表;刚到达的客户则应插入到当前 所含元素最少的队列中;若该队列在插入前为空,则还应产生一个客户离 开事件插入事件表。 客户离开时间的处理比较简单。首先计算该客户在银行逗留的时间,
然后从队列中删除该客户后查看队列是否为空,若不空则设定一个新的队 头客户离开事件。 四、实验步骤(包括主要步骤、代码分析等) 第 1 次:完成程序的主框架设计,进行调试,验证其正确性; 第 2 次:详细设计,进行调试,验证其正确性; 第 3 次:进行整体调试,运行程序,对运行结果进行分析,完成实验报告。 程序代码如下: #include #include // malloc()等 #include #include #include #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 typedef int Status; // Status 是函数的类型,其值是函数结果状态代码, 如 OK 等 #define Qu 4 // 客户队列数 typedef struct { int OccurTime; // 事件发生时刻 int NType; }Event,ElemType; typedef struct LNode { ElemType data; LNode *next; }*Link,*Position; struct LinkList // 链表类型 { Link head,tail; int len; }; typedef struct { int ArrivalTime; // 到达时刻 int Duration; // 办理事务所需时间
}QElemType; // 定义 QElemType(队列的数据元素类型)为结构体类型; typedef struct QNode { QElemType data; QNode *next; }*QueuePtr; struct LinkQueue { QueuePtr front,rear; // 队头、队尾指针 }; typedef LinkList EventList; // 事件链表类型,定义为有序链表 EventList ev; // 事件表 Event en; // 事件 Event et; // 临时变量 LinkQueue q[Qu]; // Qu 个客户队列 QElemType customer; // 客户记录 int TotalTime=0,CustomerNum=0; // 累计客户逗留时间,客户数(初值为 0) int CloseTime; // 银行营业时间(单位是分) //对链表的操作: Status InitList(LinkList &L) { // 构造一个空的线性链表 Link p; p=(Link)malloc(sizeof(LNode)); // 生成头结点 if(p) { p->next=NULL; L.head=L.tail=p; L.len=0; return OK; } else return ERROR; } Status DelFirst(LinkList &L,Link h,Link &q) { q=h->next; if(q) // 链表非空
{ h->next=q->next; if(!h->next) // 删除尾结点 L.tail=h; // 修改尾指针 L.len--; return OK; } else return FALSE; // 链表空 } ElemType GetCurElem(Link p) { // 已知 p 指向线性链表中的一个结点,返回 p 所指结点中数据元素的值 return p->data; } Status ListEmpty(LinkList L) { if(L.len) return FALSE; else return TRUE; } int ListLength(LinkList L) { return L.len; } Position GetHead(LinkList L) { // 返回线性链表 L 中头结点的位置 return L.head; } Status OrderInsert(LinkList &L,ElemType e,int (*comp)(ElemType,ElemType)) { // 已知 L 为有序线性链表,将元素 e 按非降序插入在 L 中。 Link o,p,q; q=L.head; p=q->next; while(p!=NULL&&comp(p->data,e)<0) { q=p; p=p->next;
} o=(Link)malloc(sizeof(LNode)); // 生成结点 o->data=e; // 赋值 q->next=o; // 插入 o->next=p; L.len++; // 表长加 1 if(!p) // 插在表尾 L.tail=o; // 修改尾结点 return OK; } //对队列的操作: Status InitQueue(LinkQueue &Q) { // 构造一个空队列 Q if(!(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)))) exit(OVERFLOW); Q.front->next=NULL; return OK; } Status QueueEmpty(LinkQueue Q) { // 若 Q 为空队列,则返回 TRUE,否则返回 FALSE if(Q.front==Q.rear) return TRUE; else return FALSE; } int QueueLength(LinkQueue Q) { // 求队列的长度 int i=0; QueuePtr p; p=Q.front; while(Q.rear!=p) { i++; p=p->next; } return i; } Status GetHead(LinkQueue Q,QElemType &e)
{ // 若队列不空,则用 e 返回 Q 的队头元素,并返回 OK,否则返回 ERROR QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; e=p->data; return OK; } Status EnQueue(LinkQueue &Q,QElemType e) { // 插入元素 e 为 Q 的新的队尾元素 QueuePtr p; if(!(p=(QueuePtr)malloc(sizeof(QNode)))) // 存储分配失败 exit(OVERFLOW); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; return OK; } Status DeQueue(LinkQueue &Q,QElemType &e) { // 若队列不空,删除 Q 的队头元素,用 e 返回其值,并返回 OK,否则返回 ERROR QueuePtr p; if(Q.front==Q.rear) return ERROR; p=Q.front->next; e=p->data; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front; free(p); return OK; } int cmp(Event a,Event b) { // 依事件 a 的发生时刻<、=或>事件 b 的发生时刻分别返回-1、0 或 1 if(a.OccurTime==b.OccurTime) return 0; else return (a.OccurTime-b.OccurTime)/abs(a.OccurTime-b.OccurTime); }
void OpenForDay() { // 初始化操作 int i; InitList(ev); // 初始化事件链表为空 en.OccurTime=0; // 设定第一个客户到达事件 en.NType=Qu; // 到达 OrderInsert(ev,en,cmp); // 插入事件表 for(i=0;i
分享到:
收藏