本算法用文字描述难以将清楚,笔者实力有限,做了8小时,一言难尽。出自C语言教材(严蔚敏,于伟民版)p65,B站这人思路讲的很好,大家不懂去看看,代码部分是笔者原创,不懂留言即可。相互学习,共同进步https://www.bilibili.com/video/BV1nE411u7n4?spm_id_from=333.337.search-card.all.click
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
#define QUEUE_MAX 100
int TotalTime = 0;
int CustomerNum;
typedef struct Node
{
int number;//到银行的人所进的队列
int occurTime;//时间发生时刻
int Ntype;//事件类型,0表示到达事件,1-4四个窗口离开事件
}event, *ev;
typedef struct EventList {
event data;
struct EventList *next;
} EventList, *Ev;//事件链表
typedef struct {
int ArrivalTime;
int Duration;
}Customer, *CusPtr;//顾客结构体
typedef struct {
Customer *base;
int front;
int rear;
}SqQueue;//顾客队列
int InitQueue(SqQueue &Q)
{
Q.base = (CusPtr)malloc(QUEUE_MAX* sizeof(Customer));
if (!Q.base)
return 0;
Q.front = Q.rear = 0;
return 1;
}//初始化队列
int InitCustomer(CusPtr &c)
{
c = (CusPtr)malloc(sizeof(Customer));
if (!c)
return 0;
c->ArrivalTime = 0;
c->Duration = 0;
return 1;
}
int InitList(Ev &L)
{
L = (Ev)malloc(sizeof(EventList));
if (!L)
return 0;
L->next = NULL;
return 1;
}
int InitEvent(ev &e)
{
e = (ev)malloc(sizeof(event));
if (!e)
return 0;
e->Ntype = 999;
e->occurTime = 0;
e->number = 999;
return 1;
}
void GernarateTime(int &t)
{
int i;
time_t tnow;
for (i = 0; i < 2; i++)
{
t = (int)rand() % 28800 + 0;
}
t += 1648782556;
struct tm *sttm;
tnow = t;
sttm = localtime(&tnow);
printf("当前时间为:%04u-%02u-%02u %02u:%02u:%02u\n", sttm->tm_year + 1900, sttm->tm_mon + 1, \
sttm->tm_mday, sttm->tm_hour, sttm->tm_min, sttm->tm_sec);
}
void printtime(int &t)
{
time_t tnow;
struct tm *sttm;
tnow = t;
sttm = localtime(&tnow);
printf("当前时间为:%04u-%02u-%02u %02u:%02u:%02u\n", sttm->tm_year + 1900, sttm->tm_mon + 1, \
sttm->tm_mday, sttm->tm_hour, sttm->tm_min, sttm->tm_sec);
}//将秒为单位的时间格式化
bool IsEmpty(Ev EList)
{
if (!EList->next)
return true;
else
return false;
}//链表是否为空
int EnQueue(SqQueue &Q, Customer c)
{
if ((Q.rear + 1) % QUEUE_MAX == Q.front)
return 0;
Q.base[Q.rear] = c;
Q.rear = (Q.rear + 1) % QUEUE_MAX;
return 1;
}//入队列
int OpenForDay(SqQueue &Q1, SqQueue &Q2, SqQueue &Q3, SqQueue &Q4, Ev &EList)//银行营业
{
srand(time(0));
int t = 0;
printf("尊敬的客户您好,银行在中午12点营业,17点打烊,期待您的光临\n");
GernarateTime(t);//t=1648785601+5*3600=1648803601
if (t > 1648785601 && t < 1648803601)
{
printf("银行营业中....\n");
TotalTime = 0;
CustomerNum = 0;
InitList(EList);
InitQueue(Q1);
InitQueue(Q2);
InitQueue(Q3);
InitQueue(Q4);
Ev head = (Ev)malloc(sizeof(EventList));
head->data.Ntype = 0;
head->data.occurTime = t;
head->next = NULL;
EList->next = head;
return t;
}
else
{
printf("银行尚未营业\n");
return 0;
}
}
int DeleteFrist(Ev &EList, event &e)//删除第一个元首节点
{
int nowtime;
Ev p;
p = EList->next;
nowtime = p->data.occurTime;
EList->next = EList->next->next;
e = p->data;
free(p);
if (CustomerNum != 0)
{
printtime(e.occurTime);
if (e.Ntype == 0)
{
printf("%d顾客到达,并在%d号窗口排队\n", CustomerNum, e.number);
printf("\n");
}
else
{
printf("有顾客从%d号窗口离开\n", e.Ntype);
printf("\n");
}
}
return nowtime;
}
void InsertList(Ev &EList, ev event)//升序插入事件链表算法
{
Ev p, q,r;
InitList(q);
InitList(r);
q->data = *event;
p = EList;
if (!p->next)
p->next = q;
else
{
r = p;
p = p->next;
while (p->next &&p->data.occurTime < q->data.occurTime)
{
r = r->next;
p = p->next;
}
if (!p->next)
{
if (p->data.occurTime > q->data.occurTime)
{
r->next = q;
q->next = p;
}
else
p->next = q;
}
else
{
r->next = q;
q->next = p;
}
}
}
int QLength(SqQueue Q)//队列长度
{
return (Q.rear - Q.front + QUEUE_MAX) % QUEUE_MAX;
}
int MinQueue(SqQueue Q1, SqQueue Q2, SqQueue Q3, SqQueue Q4)
{
int lenth1 = QLength(Q1);
int lenth2 = QLength(Q2);
int lenth3 = QLength(Q3);
int lenth4 = QLength(Q4);
int result = 999;
if (lenth1 <= lenth2 && lenth1 <= lenth3 && lenth1 <= lenth4)
result = 1;
if (lenth2 <= lenth1 && lenth2 <= lenth3 && lenth2 <= lenth4)
result = 2;
if (lenth3 <= lenth2 && lenth3 <= lenth1 && lenth3 <= lenth4)
result = 3;
if (lenth4 <= lenth2 && lenth4 <= lenth3 && lenth4 <= lenth1)
result = 4;
return result;
}//获取最短队列
int DeleteQueue(SqQueue &Q,Customer &c)
{
if (Q.front == Q.rear)
return 0;
c = Q.base[Q.front];
Q.front = (Q.front + 1) % QUEUE_MAX;
return 1;
}//出队列
void CustomerArravid(int t, Ev &EList, SqQueue &Q1, SqQueue &Q2, SqQueue &Q3, SqQueue &Q4)//顾客抵达算法
{
CustomerNum++;
int durtime = (int)rand() % 2400 + 600;
int interal = (int)rand() % 800 + 600;
int nextArrial = t + interal;
int minQ = MinQueue(Q1, Q2, Q3, Q4);
if (nextArrial < 1648803601)
{
ev e;
InitEvent(e);
e->Ntype = 0;
e->occurTime = nextArrial;
e->number = minQ;
InsertList(EList, e);
}
Customer c;
c.ArrivalTime = t;
c.Duration = interal;
if(minQ==1)
EnQueue(Q1,c);
if (minQ == 2)
EnQueue(Q2, c);
if (minQ == 3)
EnQueue(Q3, c);
if (minQ == 4)
EnQueue(Q4, c);
ev e0;
InitEvent(e0);
e0->Ntype = minQ;
e0->occurTime = t + durtime;
InsertList(EList, e0);
}
void CustomerDeparture(Ev &EList, SqQueue &Q1, SqQueue &Q2, SqQueue &Q3, SqQueue &Q4,event event1)//顾客离开算法
{
int i;
i = event1.Ntype;
Customer c;
if (i == 1)
DeleteQueue(Q1, c);
if (i == 2)
DeleteQueue(Q2, c);
if (i == 3)
DeleteQueue(Q3, c);
if (i == 4)
DeleteQueue(Q4, c);
TotalTime += event1.occurTime - c.ArrivalTime;
}
int main()
{
SqQueue Q1, Q2, Q3, Q4;
Ev EList;
event event0;
int nowtime;
nowtime = OpenForDay(Q1, Q2, Q3, Q4, EList);
if (nowtime != 0) {
while (!IsEmpty(EList))
{
nowtime = DeleteFrist(EList, event0);
if (event0.Ntype == 0)
CustomerArravid(nowtime, EList, Q1, Q2, Q3, Q4);
else
CustomerDeparture(EList,Q1,Q2,Q3,Q4,event0);
}
}
}
运行截图
!