银行排队问题

本文介绍了一个基于链表和队列实现的银行排队系统模拟程序。通过随机生成客户到达时间和办理业务所需时间,模拟银行的日常运营情况,并计算平均等待时间。使用了事件驱动的方式,维护一个事件链表和多个客户队列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要用队列,元素用来放客户;

用链表,元素用来放时间(时刻);

客户办理所需时间 durtime;

客户到达的时间间隔 intertime;

现在进行的时刻 occurtime.



银行排队问题

银行排队问题

“a.h”

#include
#include
#include
#include
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
#define INFEASIBLE -1
#define OVERFLOW -2

typedef int Status;

typedef struct{
int OccurTime; //事件发生时刻
int NType; //事件发生类型 0表示到达,1-4表示四个窗口离开事件
} Event,ElemType;

typedef struct LNode{ //链表用于放事件
ElemType e;
struct LNode *next;
}LNode;
typedef struct LNode *LinkList;

typedef struct{
int ArriveTime; //到达时刻
int Duration; //办理事务所需时间
} QElemType;

typedef struct QNode{ //队列用于存放排队的人
QElemType data;
struct QNode *next;
}QNode ,*QueuePtr;

typedef struct{
QueuePtr front ,rear;
}LinkQueue;

“LinkList.h”

//前面的两个函数initlist destroylist中L为双指针,所以要*L
int cmp(Event a,Event b)
{
if(a.OccurTime==b.OccurTime)
return 0;
else
return (a.OccurTime-b.OccurTime)/abs(a.OccurTime-b.OccurTime);

}
Status InitList(LinkList *L)
{
*L=(LinkList)malloc(sizeof(struct LNode));
if(!*L)
exit(OVERFLOW);
(*L)->next=NULL;
return OK;
}

Status DestroyList(LinkList *L)
{
LinkList q;
while(*L){
q=(*L)->next;
free(*L);
*L=q;
}
return OK;
}

Status ClearList(LinkList L)
{
LinkList p=L->next;
L->next=NULL;
while(p){
free(p);
p=p->next;
}
return OK;
}

Status ListEmpty(LinkList L)
{
if(L->next==NULL){
return TRUE;
}else{
return FALSE;
}
}

Status ListLength(LinkList L)
{
int i=0;
LinkList p;
p=L;
while(p->next){
p=p->next;
i++;
}
return i;
}

Status GetElem(LinkList L,int i,ElemType *e)
{
int j;
LinkList p=L;
for(j=0;j
p=p->next;
}
if(p==NULL){
return ERROR;
}
*e=p->e;
return OK;
}

Status LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType)) //
{
LinkList p=L;
int i=0;
while(p){
p=p->next;
i++;
if(compare(p->e,e))
return i;
printf("**********%d\n",i);
}
return 0;
}

Status PriorElem(LinkList L,ElemType cur_e,ElemType *pre_e)
{
LinkList p,q;
p=L->next;
while(p->next){
q=p->next;
if(q->e.NType==cur_e.NType&&q->e.OccurTime==cur_e.OccurTime){
*pre_e=p->e;
return OK;
}
p=q;
}
return INFEASIBLE;
}

Status NextElem(LinkList L,ElemType cur_e,ElemType *next_e)
{
LinkList p;
p=L;
while(p->next){
p=p->next;
if(p->e.NType==cur_e.NType&&p->e.OccurTime==cur_e.OccurTime){
*next_e=p->next->e;
return OK;
}
}
return INFEASIBLE;
}

Status ListInsert(LinkList *L,int i,ElemType e)
{
LinkList p=(*L),q;
int j=0;
while(p&&j
p=p->next;
j++;
}
if(!p||j>i-1){
return ERROR;
}
q=(LinkList)malloc(sizeof(struct LNode));
q->e=e;
q->next=p->next;
p->next=q;
return OK;
}

Status ListDelete(LinkList *L,int i,ElemType *e)
{
LinkList p=(*L),q;
int j=0;
if(i>ListLength((*L))||i<1){
return ERROR;
}
while(p&&j
p=p->next;
j++;
}
q=p->next;
p->next=q->next;
*e=q->e;
free(q);
return OK;
}

Status ListTraverse (LinkList L,void(*vi)(Elemtype))
{
LinkList p=L->next;
printf("*******时间表:");
while(p){
vi(p->e);
p=p->next;
}
printf("\n");
return OK;
}


Status OrderInsert(LinkList *L,ElemType e,int(*cmp)(ElemType ,ElemType))
{
LinkList p,s;
LinkList q=(*L);
p=q->next;
while(p!=NULL&&cmp(e,p->e)==1) //一定要注意这边要等于1来判定对错
{
q=p;
p=p->next;
}
s=(LinkList)malloc(sizeof(struct LNode));
s->e=e;
q->next=s;
s->next=p;

return OK;
}

Status DelFirst(LinkList *L,ElemType *e)
{
LinkList p;
p=(*L)->next;
(*L)->next=p->next;
*e=p->e;
free(p);
return OK;
}

"Queue.h"

Status InitQueue(LinkQueue *q)
{
(*q).front=(QNode*)malloc(sizeof(QNode));
if(!(*q).front)
return ERROR;
(*q).rear=(*q).front;
(*q).front->next=NULL;
return TRUE;
}

Status DestroyQueue(LinkQueue *q)
{
while((*q).front){
(*q).rear=(*q).front->next;
free((*q).front);
(*q).front=(*q).rear;
}
return OK;
}

Status ClearQueue(LinkQueue *q)
{
QueuePtr p=(*q).front->next;
while(p){
(*q).rear=p->next;
free(p);
p=(*q).rear;
}
(*q).rear=(*q).front=NULL;
return OK;

}

Status QueueEmpty(LinkQueue q)
{
if(q.front!=q.rear)
return FALSE;
else
return TRUE;
}

int QueueLength(LinkQueue q)
{
int i=0;
QueuePtr p=q.front;
while(q.rear!=p){
p=p->next;
i++;

}
return i;
}

Status GetHead(LinkQueue q,QElemType *e)
//取队头元素
{
if(q.front==q.rear)
return ERROR;
(*e)=q.front->data;
return TRUE;
}

Status InsertQueue(LinkQueue *q,QElemType e)
//添加元素,从队尾插入
{
QueuePtr p=(QNode *)malloc(sizeof(QNode));
if(!p)
return ERROR;
p->data=e;
p->next=NULL;
(*q).rear->next=p;
(*q).rear=p;
return OK;
}
Status DeleteQueue(LinkQueue *q,QElemType *e)
//删除元素,从队头删除
{
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;
}
Status QueueTraverse(LinkQueue q,Status(*fun)(QElemType))
{
QueuePtr p=q.front->next;
printf("队头");
while(p){
fun(p->data);
p=p->next;
}
printf("队尾\n");
return OK;
}

"Bank.h"

#include"a.h"
#include"LinkList.h"
#include"Queue.h"

#define QN 4 //定义队列数为4
#define CAG 5 //定义客户到达间隔最大为5
#define CDG 30 //定义客户办理业务时间最大为30
#define CloseTime 50

LinkList el;
Event en; //主事件
Event e; //事件的临时变量
LinkQueue q[QN];
QElemType customer;
int TotalTime=0,CustomerNum=0;


void print(ElemType e)
{
printf(" %d ",e.OccurTime);
}

void OpenForDay()
{
int i;
InitList(&el);
en.OccurTime=0; en.NType=0;
OrderInsert(&el,en,cmp);
for(i=0;i
InitQueue(&q[i]);
printf("银行开始营业!!\n");
}
void Random(int *d,int *i)
{
*d=rand()�G+1;
*i=rand()�G+1;
}

int Minimum(LinkQueue q[])
{
int l[QN],i=1,min=0;
for(i=0;i
l[i]=QueueLength(q[i]);
for(i=0;i
if(l[0]>l[i]){
l[0]=l[i];
min=i;
}
return min;
}

void CustomerArrived() //occurtime即为用户到达时间
{
int durtime,intertime,i;
Event e;
printf("新的客户到达\n");
++CustomerNum;
Random(&durtime,&intertime); //随机生成一个用户的办理所需的时间和下一个用户的到达时间
printf("现在的时间是 %d,办理所需时间 %d,下一客户到达时间 %d\n",en.OccurTime,durtime,en.OccurTime+intertime);
e.OccurTime=en.OccurTime+intertime;
e.NType=0;
if(e.OccurTime
OrderInsert(&el,e,cmp);
i=Minimum(q);
customer.ArriveTime=en.OccurTime;
customer.Duration=durtime;
InsertQueue(&q[i],customer);
if(QueueLength(q[i])==1){ //该用户不需要等待
e.OccurTime=en.OccurTime+durtime;
e.NType=(++i);
OrderInsert(&el,e,cmp);
}
}

void CustomerDeparture()
{
Event e;
int i;
i=en.NType;
printf("第 %d 队的客户离开\n",i);
DeleteQueue(&q[i-1],&customer);
TotalTime+=en.OccurTime-customer.ArriveTime;
if(!QueueEmpty(q[i]))
{
DeleteQueue(&q[i],&customer);
e.NType=i+1;
e.OccurTime=en.OccurTime+customer.Duration;
OrderInsert(&el,e,cmp);
}
}

void Bank_Simulation() //银行模拟仿真
{
ElemType p;
OpenForDay();
while(!ListEmpty(el)){

DelFirst(&el,&p);
en.OccurTime=p.OccurTime;
en.NType=p.NType;
ListTraverse(el,print);
if(en.NType==0)
CustomerArrived();
else
CustomerDeparture();
}
printf("顾客总数; %d,所有顾客共耗时: %d,平均耗时; %d",CustomerNum,TotalTime,TotalTime/CustomerNum);
}

"main.h"
#include"Bank.h"
int main()
{
Bank_Simulation();
return OK;
}

//活期储蓄处理中,储户开户、销户、存入、支出活动频繁,系统设计要求: //1)能比较迅速地找到储户的帐户,以实现存款、取款记账; //2)能比较简单,迅速地实现插入和删除,以实现开户和销户的需要。 #include #include #include using namespace std; int total; //初始时银行现存资金总额 int closeTime; //营业结束时间 int arriveTime; //两个到达事件之间的间隔上限 int dealTime; //客户之间交易的时间上限 int dealMoney = 30000; //交易额上限 int currentTime = 0; //当前时间 int totalTime = 0; //客户逗留总时间 int counter = 0; //客户总数 int number = 1; //初始客户序列号+ struct service { int num; //客户号 string type; //到达或离开 int beginTime; int endTime; int money; //正数为存款,负数为取款 service* next; }; struct queue { //队列 service* head; service* rear; }; void push(queue &q,int d) {// 插入元素d为Q的新的队尾元素 service* temp = new service; temp->money = d; temp->next = NULL; if(NULL == q.head) {//队列为空,初始化 q. head = temp; q. rear = temp; }//if else {//队列不为空,插入元素d q. rear->next = temp; q. rear = q.rear->next; }//else } void pop(queue &q) {// 若队列不空,出对列函数 service* temp; temp = q. head; if(NULL ==q. head->next) q.head = q. rear =NULL; else q. head=q. head->next; delete temp; } service* front(queue &q) {//返回队首元素 return q. head; } service* back(queue &q) {//返回队尾元素 return q. rear; } service* searchAndDel(queue &q,int m) {//在队列中寻找可处理元素 service* sign = q. head; //标记头节点 service* temp; while(NULL != q. head) { if((-(q. head->money)) next; // 首节点后移一位,返回原首节点 return temp; // 开办.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include "stdlib.h" #include "string.h" #include "ctype.h" #include #include /* ---------------- */ void apply(); /* 申请帐号 */ void land(); /* 登陆系统 */ void finds(); /* 查询存款 */ void saving(); /* 存钱 */ void get(); /* 取款 */ void turn(); /* 转帐 */ /* --------------------- */ struct per { char name[20]; char accounts[20]; char password[20]; int money; }dat,temp; /* ----------- */ void manage() /* 主函
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值