银行业务模拟

一、题目

 

详见<数据结构与c语言>(严蔚敏) p65

 

二、实现

 

 

/*****************************************************************
*功  能:模拟银行的业务
*作  者:JarvisChu
*时  间:2010.11.27
*备  注:《数据结构 c语言版》(严蔚敏) p67
******************************************************************/ 

#include <stdio.h>
#include <malloc.h>

//---------------------------数据结构定义---------------------------------------------

typedef struct Event{                //事件
	int OccurTime;                   //事件发生时间
	int NType;                       //事件类型 0 表示到达事件 1~4表示四个窗口的离开时间
	struct Event* next;              //指向下一条事件
}Event,ElemType;

typedef struct{                      //事件表(按照事件发生时间排序)
	Event * pHead;
}EventList;

typedef struct QElemType{            //队列元素
	int ArriveTime;                  //到达时间
	int Duration;                    //办理业务所需时间
	struct QElemType* next;          //下一个客户信息
}QElemType;

typedef struct{
	QElemType* front;                //队首
	QElemType* rear;                 //队尾
}Queue;

//--------------------------全局变量定义----------------------------------------------

EventList *ev_list;                  //事件表
//Event *event;                        //事件
Queue q[5];                          //四个客户队列
int TotalTime;                       //客户逗留总时间
int CustomerNum;                     //客户数
int CloseTime;

//--------------------------链表操作------------------------------------------------

//初始化链表
void InitEventList(EventList* el){
	el->pHead = (Event *)malloc(sizeof(Event));
	el->pHead->next = NULL;
}

//按序插入
void OrderInsertEvent(EventList* el,Event* ev){
	Event* pEv = NULL;
	pEv = el->pHead->next;                           //第一个事件
	if(pEv == NULL){                                 //空表
//		printf("空表\n");
		el->pHead->next = ev;
		ev->next = NULL;
//		printf("%d\n",el->pHead->next->OccurTime);
		//printf("%d\n",pEv->OccurTime);
		return;
	}
	if(pEv->OccurTime > ev->OccurTime){              //该事件小于第一个事件
//		printf("小于第一个事件\n");
		ev->next = el->pHead->next;
		el->pHead->next = ev;
		return;
	}
	while (pEv->next != NULL && (pEv->next->OccurTime < ev->OccurTime)){          //
		pEv = pEv->next;
	}
	if(pEv->next == NULL){                            //该事件在表尾
		pEv->next = ev;
		ev->next = NULL;
		return;
	}
	else{
		ev->next = pEv->next;
		pEv->next = ev;
		return;
	}
}

//删除头结点
Event* deleteHead(EventList* el){
	Event* del = NULL;
	del = el->pHead->next;                         //表中第一个事件
	if(del != NULL){                               //表中有事件
		el->pHead->next = el->pHead->next->next;
	}
	return del;
}


//显示节点
void EventDisplay(Event* ev){
	printf("OccurTime = %d ,NType = %d \n",ev->OccurTime,ev->NType);
}

//显示事件表
void EventListDisplay(EventList* el){
	Event* pEv;
	pEv = el->pHead->next;                           //第一个事件
	while(pEv != NULL){                                 //空表
		EventDisplay(pEv);
		pEv = pEv->next;
	}
}

//--------------------------队列操作------------------------------------------------

//初始化队列
void InitQueue(Queue* qu){
	qu->front = qu->rear = (QElemType*)malloc(sizeof(QElemType));
	qu->front->next = NULL;
}

//入队
void EnQueue(Queue* qu,QElemType* elem){
//	QElemType * tmp;
//	tmp = (QElemType*)malloc(sizeof(QElemType));
//	tmp->ArriveTime = elem->
	elem->next = NULL;
    qu->rear->next = elem;
	qu->rear =qu->rear->next; //elem;
	

}

//出队
QElemType* DeQueue(Queue* qu){
	QElemType* del= NULL;
	if(qu->front == qu->rear)               //空队
		return NULL;
	del = qu->front->next;
	qu->front = qu->front->next;
	//if(del != NULL){
	//	qu->front->next = qu->front->next->next;
	//}

	return del;
}

//队列长度
int NumOfQueue(Queue* qu){
	int i = 0;
	QElemType* pQE;
	if(qu->front == qu->rear)               //空队
		return 0;

	pQE =  qu->front->next;                         //第一个事件
	while(pQE != NULL){                                 //空表
		i++;
		pQE = pQE->next;
	}
	return i;
}

//比较大小,返回最小索引
int min(int a,int b,int c,int d){
	int i;
	int num[4];
	int index = 0;
	int minnum = a;
	
	num[0] = a;
	num[1] = b;
	num[2] = c;
	num[3] = d;

	for(i=0;i<4;i++){
		if(minnum > num[i]){
			minnum = num[i];
			index = i;
		}
	}

	return (++index);	
}

//显示队列节点
void QueueElemDisplay(QElemType* elem){
	printf("ArriveTime = %d ,Duration = %d \n",elem->ArriveTime,elem->Duration);
}

//显示队列
void QueueDisplay(Queue* qu){
	
	QElemType* pQE;
	pQE =  qu->front->next;                          //第一个事件
	while(pQE != NULL){                                 //空表
		QueueElemDisplay(pQE);
		pQE = pQE->next;
	}
}

//--------------------------业务处理--------------------------------------

//银行开门
void OpenForDay(){
	int i;
	Event* event;
	TotalTime = 0;
	CustomerNum = 0;
	printf("              银行开始营业\n");
	printf("*****************************************\n");
	ev_list = (EventList *)malloc(sizeof(EventList));
	InitEventList(ev_list);    //初始化事件表
	for(i=0;i<5;i++)           //初始化四个窗口队列
		InitQueue(&q[i]);
	event = (Event*)malloc(sizeof(Event));
	event->OccurTime = 0;      //设定第一个客户的到达事件
	event->NType = 0;
	OrderInsertEvent(ev_list,event);

//	EventListDisplay(ev_list);
}

//处理客户到达事件
void CustmerArrived(Event* ev){
	
	int durtime;                //本客户处理业务事件
	int intertime;				//下一个客户将在intertime时间后到
	int minQueue;
	int occurtime;              //事件发生时间
	Event* event_in;
	Event* event_out;
	QElemType* elem;
	CustomerNum++;
	durtime = rand()%100;
	intertime = rand()%100+2;
    
	occurtime = ev->OccurTime;

//   printf("客户到达:OccurTime = %d\n",ev->OccurTime);
    printf("%-4d时刻:客户到达 ",ev->OccurTime);

	elem = (QElemType*)malloc(sizeof(ElemType));
	elem->ArriveTime = occurtime;
	elem->Duration = durtime;

	if((occurtime+intertime) < CloseTime){ //将下一个客户的达到事件插入事件表
		event_in = (Event*)malloc(sizeof(Event));
		event_in->OccurTime = occurtime+intertime; //下一个客户的达到时间
		event_in->NType = 0;                       //到达事件
	//	printf("下一个客户达到时间 %d\n",event_in->OccurTime);
		OrderInsertEvent(ev_list,event_in);
	//	EventListDisplay(ev_list);

	}
	else{
		//printf("银行要关门,下一个客户进不来\n");
	}
   
	//minQueue 为当前最短的队列的 序号
	minQueue = min(NumOfQueue(&q[1]),NumOfQueue(&q[2]),NumOfQueue(&q[3]),NumOfQueue(&q[4]));

	printf("进入%d号窗口\n",minQueue);

	EnQueue(&q[minQueue],elem);         //该客户进入一个窗口队列

//	printf("客户进入窗口后 窗口情况\n");
//	QueueDisplay(&q[minQueue]);
//	printf("队列长度为 %d\n",NumOfQueue(&q[minQueue]));

	if(NumOfQueue(&q[minQueue]) == 1){        //说明该客户入队之前,队列为空
		event_out = (Event*)malloc(sizeof(Event));
		event_out->OccurTime = occurtime+durtime; //该客户的离开事件
		event_out->NType = minQueue;          //窗口minQueue的离开事件
		OrderInsertEvent(ev_list,event_out);
	}
	printf("\n");

   // EventListDisplay(ev_list);
	
}

//客户离开事件
void CustomerDeparture(Event* ev){
	QElemType* customer;
	Event* e;
	customer = DeQueue(&q[ev->NType]);          //摘取队列的客户
	TotalTime +=  ev->OccurTime-customer->ArriveTime; //该用户花费总时间
   
//	printf("客户离开:OccurTime = %d\n",ev->OccurTime);
	printf("%-4d时刻:%d号窗口 客户离开\n",ev->OccurTime,ev->NType);
	printf("\n");
	if(NumOfQueue(&q[ev->NType]) != 0){        //队列不是空
		e = (Event*)malloc(sizeof(Event));
		e->NType = ev->NType;                  //队列NType的离开事件
		e->OccurTime = ev->OccurTime+q[ev->NType].front->next->Duration;
		OrderInsertEvent(ev_list,e);
	}

}

//开始模拟
void Bank_Simulation(int closetime){
	Event* evt;int i;
//	evt = (Event*)malloc(sizeof(Event));
	CloseTime = closetime;                    //银行关门时间
	OpenForDay();                             //开门
	evt = deleteHead(ev_list);
    i=0;
	while( evt != NULL){
//		printf("取得事件 %d\n",evt->NType);
		if(evt->NType == 0){
			CustmerArrived(evt);
		}
		else{
			CustomerDeparture(evt);
		}
/*		printf("取得头结点前\n");
		printf("---------------事件表---------\n");
		EventListDisplay(ev_list);
		for(i=1;i<5;i++){
			printf("-------------窗口%d--------\n",i);
			QueueDisplay(&q[i]);
		}*/
		evt = deleteHead(ev_list);	
	}

	printf("*****************************************\n");
	printf("              银行结束营业\n");

	printf("业务统计结果如下:\n");
	printf("接待客户总人数为:%d\n",CustomerNum);
	printf("处理业务总时间为:%d\n",TotalTime);
	printf("平均处理时间为:  %d\n",TotalTime/CustomerNum);
}

//--------------------------主函数------------------------------------------------

void main(){
//    int i;
	Bank_Simulation(1200);

//--------------------下面代码作用为:测试队列与链表功能

/*
//	EventListDisplay(ev_list);
//		for(i=1;i<5;i++){
//				printf("-------------窗口%d--------\n",i);
//				QueueDisplay(&q[i]);
//		}
//	Event* ev1,*ev2,*ev3,*ev4;
//	QElemType *qelem1,*qelem2,*qelem3;
//	EventList* el;
//	Queue* queue;
//	ev1 = (Event*)malloc(sizeof(Event));
//	ev2 = (Event*)malloc(sizeof(Event));
//	ev3 = (Event*)malloc(sizeof(Event));
//	el = (EventList*)malloc(sizeof(EventList));

	qelem1 = (QElemType *)malloc(sizeof(QElemType));
	qelem2 = (QElemType *)malloc(sizeof(QElemType));
	qelem3 = (QElemType *)malloc(sizeof(QElemType));
	queue = (Queue*)malloc(sizeof(Queue));

//	ev1->OccurTime = 2;
//	ev1->NType = 0;
//	ev2->OccurTime = 1;
//	ev2->NType = 1;
//	ev3->OccurTime = 4;
//	ev3->NType = 2;

	qelem1->ArriveTime = 0;
	qelem1->Duration = 1;
	qelem2->ArriveTime = 1;
	qelem2->Duration = 2;
	qelem3->ArriveTime = 2;
	qelem3->Duration = 3;

//	InitEventList(el);
	InitQueue(queue);

//	OrderInsertEvent(el,ev1);
//	EventListDisplay(el);

//	printf("%d\n",el->pHead->next->OccurTime);

//	printf("------------------------\n");

//	OrderInsertEvent(el,ev2);
//	EventListDisplay(el);

//	printf("------------------------\n");
	
//	OrderInsertEvent(el,ev3);
//	EventListDisplay(el);

//	printf("------------------------\n");

//	ev4 = deleteHead(el);
//	printf("%d\n",ev4->NType);

//	deleteHead(el);
//	ev4 = deleteHead(el);
//	printf("%d\n",ev4->NType);
//	ev4 = deleteHead(el);
//	printf("%d\n",ev4->NType);
	
//	deleteHead(el);
//	deleteHead(el);
//	deleteHead(el);
//	EventListDisplay(el);

	printf("%d ",NumOfQueue(queue));
    printf("--------入队---------\n");
	EnQueue(queue,qelem1);
	printf("队列长度为 %d \n",NumOfQueue(queue));
	QueueDisplay(queue);

    printf("-------出对------------\n");
    DeQueue(queue);
	QueueDisplay(queue);

	printf("--------入队-------------\n");
	EnQueue(queue,qelem2);
	printf("%d \n",NumOfQueue(queue));
	QueueDisplay(queue);

	printf("--------入队-----------\n");
	EnQueue(queue,qelem3);
	printf("%d \n",NumOfQueue(queue));
	QueueDisplay(queue);

//	printf("------------------------\n");
//	DeQueue(queue);
//	DeQueue(queue);
//	DeQueue(queue);
//	DeQueue(queue);
//	printf("%d \n",NumOfQueue(queue));
//	QueueDisplay(queue);
*/
}


 

posted @ 2010-11-27 22:11  JarvisChu  阅读(289)  评论(0编辑  收藏  举报