链队列
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,* QueuePtr;
typedef struct
{
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
} LinkQueue;
1.构造空队列
Status InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!Q.front)
exit(OVERFLOW); //存储分配失败
Q.front->next=NULL;
return OK;
}
2.销毁队列Q
Status DestroyQueue(LinkQueue &Q)
{
while(Q.front)
{
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;
}
return OK;
}
插入元素e为Q的新的队列元素
Status EnQueue(LinkQueue &Q,QElemType e)
{
//插入元素e为Q的新的队列元素
p=(QueuePtr)malloc(size(QNode));
if(!p)
exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return OK;
}
队列不空,则删除Q的队头元素
Status DeQueue(LinkQueue &Q,QElemType & e)
{
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK
//否则返回ERROR
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;
}
循环队列模块说明
#define MAXQSIZE 100
typedef struct
{
QElemType * base;
int front;
int rear;
}SqQueue;
Status InitQueue(SqQueue & Q)
{ //构造一个空队列Q
Q.base=(QElemType *)malloc(MAXQSIZE * sizeof(QElemType));
if(!Q.base)
exit(OVERFLOW); //内存分配失败
Q.front=Q.rear=0;
return OK;
}
int QueueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXQSIZE) % MAXQSIZE;
}
Status DeQueue (SqQueue & Q,QElemType e)
{
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK
if(Q.front==Q.rear)
return ERROR;//队列满
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}
Status EnQueue(SqQueue &Q,QElemType e)
{
if((Q.rear+1)%MAXQSIZE==Q.front)
return ERROR;
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}
typedef struct
{
int OccurTime;//时间发送时刻
int NType; //时间类型,0表示到达时间,1-4表示离开时间
}Event,ElemType;
typedef LinkList EventList//事件链表类型,定义为有效链表
typedef struct
{
int ArrivalTime; //到达时刻
int Duration; //办理事务所需时间
}QElemType; //队列的数据元素类型
EventList ev; //事件表
Event en; //事件
LinkQueue q[5]; //4个客户队列
QElemType customer;//客户记录
int TotalTime,CustomerNum; //累计客户逗留时间,客户数
int cmp(Event a,Event b);
void OpenForDay()
{ //初始化操作
TotalTime=0;
CustomerNum=0; //初始化累计时间和客户数为0
InitList(ev); //初始化链表为空表
en.OccurTime=0; //设定第一个客户到达事件
en.NType=0;
OrderInsert(ev,en,cmp);//插入时间表
for(i=1;i<=4;++i)
InitQueue(q[i]); //置空队列
}
void CustomerArrived()
{
//处理客户到达时间,en.NType=0;
++CustomerNum;
Random(durtime,intertime);
t=en.OccurTime+intertime;
if(t<CloseTime) //银行尚未关门,插入时间表
{
OrderInsert(ev,(t,0),cmp);
}
i=Minimum(q); //求长度最短队列
EnQueue(q[i],(en.OccurTime,durtime));
if(QueueLength(q[i])==1)
{
OrderInsert(ev,(en.OccurTime+durtime,i),cmp);
} //设定第i队列的一个离开事件并插入事件表
}//CustomerArrived
void CustomerDeparture()
{
//处理客户离开事件,en.NType>0
i=en.NType;
DelQueue(q[i],customer);
TotalTime+=en.OccurTime-customer.ArrivalTime;//累计客户逗留时间
if(!QueueEmpty(q[i]))
{
GetHead(q[i],customer);
OrderInsert(ev,(en.OccurTime+curtomer.Duration,i),(*cmp)());
}
OrderInsert(ev,(en.OccurTime+curtomer.Duration,i),(*cmp)());
}//CustomerDeparture
void Bank_Simulation(int CloseTime)
{
OpenForDay();
while(!ListEmpty(ev))
{
DelFirst(GetHead(ev),p);
en=GetCurElem(p);
if(en.NType==0)
CustomerArrived(); //处理客户到达事件
else
CustomerDeparture();//处理客户离开事件
}
printf("The Average Time is %f
",(float)TotalTime/CustomerNum);
}//Bank_Simulation