#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<malloc.h>
typedef struct Qnode
{
int arrivetime;//到达时间
int duration;//离开时间
struct Qnode *next;
}QNode,*Queueptr;
typedef struct linkqueue
{
QNode *front;//指向队头
QNode *rear;//指向队尾
}LinkQueue;
LinkQueue InitQueue()//初始化属性
{
LinkQueue* PtrQ; QNode* p;
PtrQ = (LinkQueue*)malloc(sizeof(LinkQueue));
p = (QNode*)malloc(sizeof(QNode));
p->next = NULL;
PtrQ->front= PtrQ->rear = p;
return(*PtrQ);
}
void enQueue(LinkQueue* PtrQ, LinkQueue queue[],int min, QNode* tempclient)
{
queue[min].rear->next= tempclient;
PtrQ->rear = tempclient;
tempclient->next = NULL;
}//入队
int deQueue(LinkQueue* PtrQ, LinkQueue queue[], int win, QNode* tempclient)
{
QNode* p;
p = queue[win].front->next;
tempclient->arrivetime = p->arrivetime;
tempclient->duration = p->duration;//离开事件暂存
PtrQ->rear = PtrQ->front;
free(p);
return 1;
}//出队
int findmin(LinkQueue* PtrQ, LinkQueue queue[])
{
int min = 0, i = 0, j = 0; LinkQueue* q; QNode* p; int temp = 100;
for (q=queue; i <= 3;q++)
{
j = 0; p =queue[i] .front->next;
while (!(p == NULL))
{
p = p->next;
j++;
}
i++;
if (j < temp) temp = j,min=i;
}
return min;
}//找到人数最少的队列窗口
int queuelength(LinkQueue* PtrQ, LinkQueue queue[], int min)
{
int l = 0;
QNode* p ;
p = PtrQ->front->next;
while (!(p == NULL))
{
p = p ->next;
l++;
}
return l;
}//计算队列窗口长度
typedef struct evnode
{
int occurtime;//事件发生时间
int ntype;//事件类型,-1表示到达时间,0-3表示四个窗口
struct evnode* next;//指针域
}evNode, evptr;
typedef struct evlist
{
evNode head;//指向队头
evNode* rear;//指向队尾
}evList;
evList InitevList()//初始化属性
{
evList* PtrM; evNode* p;
PtrM = (evList*)malloc(sizeof(evList));
p = (evNode*)malloc(sizeof(evNode));
p->next = NULL;
PtrM->head = PtrM->rear= p;
return(*PtrM);
}
void addNode(evList* PtrM, evNode* tempptr)
{
evNode* q; evNode* p;
p = PtrM->head->next;
q = PtrM->head;
if (PtrM->head->next == NULL)
{
PtrM->head->next = tempptr;
PtrM->rear = tempptr;
}
else
{
while (p != NULL)
{
if (tempptr->occurtime < p->occurtime)
{
q->next = tempptr;
tempptr->next = p;
}
else
{
q = p;
p = p->next;
}
}
q->next = tempptr;
}
}//将离开事件和到达事件加入事件链表
int EisEmpty(evList* PtrM)
{
if (PtrM->head== PtrM->rear) return 1;
else return 0;
}//判断事件链表是否为空
int deList(evList* PtrM, evNode* item)
{
evNode* p;
if (EisEmpty(PtrM)) return 1;
else
{
p = PtrM->head->next;
item = p;
item->occurtime = p->occurtime;
item->ntype = p->ntype;
PtrM->head->next = p->next;
}
free(p);
return 0;
}//删除事件
void transItem(evNode* itemptr, evNode* item)
{
itemptr->occurtime = item->occurtime;
itemptr->ntype = item->ntype;
itemptr->next = NULL;
}//将事件链表的首个事件转入处理事件
int main()
{
int dur ; int inter ;
int CLOSE_TIME;
printf("请输入营业时间:");
scanf_s("%d", &CLOSE_TIME);
int customernum = 0;
int totaltime = 0;
LinkQueue* PtrQ= (LinkQueue*)malloc(sizeof(LinkQueue));
evList* PtrM= (evList*)malloc(sizeof(evList));
*PtrQ=InitQueue();//初始化队列窗口
*PtrM=InitevList();//初始化事件链表
LinkQueue queue[5];//4个队列
evNode* itemptr; itemptr = (evNode*)malloc(sizeof(evNode)); itemptr->next = NULL;//创建处理事件
evNode* tempptr; tempptr = (evNode*)malloc(sizeof(evNode)); tempptr->next = NULL;//创建临时事件
QNode* tempclient;tempclient= (QNode*)malloc(sizeof(QNode));tempclient->next = NULL;//创建临时客户事件
evNode* item; item = (evNode*)malloc(sizeof(evNode)); item->next = NULL;
itemptr->occurtime = 0; itemptr->ntype = -1;//创建事件处理对象
evNode* firstptr; firstptr = (evNode*)malloc(sizeof(evNode)); firstptr->next = NULL;
firstptr->occurtime = 0; firstptr->ntype = -1;
addNode(PtrM, firstptr);
while (!(EisEmpty(PtrM)))
{
deList(PtrM, item);
transItem(itemptr,item);//将事件链表的首个事件放入处理事件
if (itemptr->ntype == -1)//客户到达事件
{
customernum++;
dur = rand()%20+1;
inter = rand()%30+1;//随机生成下一个客户到达的间隔时间和服务时间
if (itemptr->occurtime + inter < CLOSE_TIME)
{
tempptr->occurtime = itemptr->occurtime + inter;
tempptr->ntype = -1;
addNode(PtrM, tempptr);
}//判断下一客户的到达时间是否已经超过银行营业时间
int min = findmin(PtrQ, queue);//排队人数最小队列下标
tempclient->arrivetime = tempptr->occurtime;
tempclient->duration = dur;
enQueue(PtrQ, queue,min,tempclient);//创建下一客户事件并插入队列窗口
if (queuelength(PtrQ, queue, min) == 1)
{
tempptr->occurtime = itemptr->occurtime + dur;
tempptr->ntype =min;
addNode(PtrM, tempptr);
}//若该窗口只一人,则预计离开时间并创建第一个离开事件将其加入事件链表
}
else//客户离开事件
{
int win = itemptr->ntype;//获得客户所在窗口号
deQueue(PtrQ, queue, win,tempclient);//出队
totaltime = itemptr->occurtime - tempclient->arrivetime;//计算当前离开客户逗留时间
if ((queuelength(PtrQ, queue, win))!=0)//若还有人排队
{
tempptr->occurtime = itemptr->occurtime + queue[win].front->next->duration;
tempptr->ntype = win;//将下一客户的数据存入临时事件中
addNode(PtrM, tempptr);//将临时事件存入事件链表中
}
}
}
printf("%f" ,totaltime * 1.0 / customernum);//计算平均客户逗留时间
}
没有显示编译错误,但是运行的时候出现了图片中的问题