Compare commits

..

1 Commits

Author SHA1 Message Date
刘彩月 47962c3335 Merge branch 'master' into 刘彩月
1 year ago

File diff suppressed because it is too large Load Diff

@ -11,63 +11,64 @@
typedef int Status; typedef int Status;
typedef struct typedef struct
{ {
int OccurTime; // 事件发生时刻 int OccurTime;//事件发生时刻
int NType; // 事件类型0表示到达事件1-4表示四个窗口的离开事件 int NType;//事件类型0表示到达事件1-4表示四个窗口的离开事件
} Event, ElemType; }Event, ElemType;
typedef struct LNode typedef struct LNode
{ {
ElemType data; ElemType data;
struct LNode *next; struct LNode* next;
} LNode, *LinkList; }LNode, * LinkList;
typedef LinkList EventList; typedef LinkList EventList;
typedef struct typedef struct
{ {
int ArrivalTime; // 到达时刻 int ArrivalTime;//到达时刻
int Duration; // 办理事务所需事件 int Duration;//办理事务所需事件
} QElemType; }QElemType;
typedef struct QNode typedef struct QNode
{ {
QElemType data; QElemType data;
struct QNode *next; struct QNode* next;
} QNode, *QueuePtr; }QNode, * QueuePtr;
typedef struct typedef struct
{ {
QueuePtr front; // 队头指针 QueuePtr front;//队头指针
QueuePtr rear; // 队尾指针 QueuePtr rear;//队尾指针
} LinkQueue; }LinkQueue;
EventList ev; // 事件表
Event en; // 事件 EventList ev;//事件表
LinkQueue q[5]; // 四个客户队列 Event en;//事件
QElemType customer; // 客户记录 LinkQueue q[5];//四个客户队列
QElemType customer;//客户记录
int TotalTime, CustomerNum, CloseTime; int TotalTime, CustomerNum, CloseTime;
void Bank_Simulation(int CloseTime); // 银行业务模拟,统计一天内客户在银行逗留的平均时间 void Bank_Simulation(int CloseTime);//银行业务模拟,统计一天内客户在银行逗留的平均时间
int cmp(Event a, Event b); // 比较事件发生先后 int cmp(Event a, Event b);//比较事件发生先后
void OpenForDay(); // 银行开门 void OpenForDay();//银行开门
void OrderInsert(EventList L, Event en, int (*cmp)(Event a, Event b)); // 插入事件 void OrderInsert(EventList L, Event en, int(*cmp)(Event a, Event b));//插入事件
void CustomerArrived(); // 客户进门 void CustomerArrived();//客户进门
void CustomerDepature(); // 客户离开 void CustomerDepature();//客户离开
int Minimum(LinkQueue Q[5]); // 求长度最短队列 int Minimum(LinkQueue Q[5]);//求长度最短队列
Status InitList(LinkList &L); // 链表初始化 Status InitList(LinkList& L);//链表初始化
Status ListInsert_L(LinkList &L, int i, ElemType e); // 在第i个位置之前插入元素e Status ListInsert_L(LinkList& L, int i, ElemType e);//在第i个位置之前插入元素e
Status ListEmpty(LinkList L); // 判断链表是否为空 Status ListEmpty(LinkList L);//判断链表是否为空
Status DelFirst(LinkList L, LNode *&q); // 删除链表中第一个结点并以q返回 Status DelFirst(LinkList L, LNode*& q);//删除链表中第一个结点并以q返回
LNode *GetHead(LinkList L); // 返回链表头结点 LNode* GetHead(LinkList L);//返回链表头结点
ElemType GetCurElem(LNode *p); // 已知p指向线性链表中的一个结点返回p所指结点中元素的值 ElemType GetCurElem(LNode* p);//已知p指向线性链表中的一个结点返回p所指结点中元素的值
void PrintEventList(); // 打印事件链表 void PrintEventList();//打印事件链表
Status ListTraverse(LinkList &L); // 遍历链表  Status ListTraverse(LinkList& L);//遍历链表 
Status InitQueue(LinkQueue &Q); // 链队列的初始化 Status InitQueue(LinkQueue& Q);//链队列的初始化
Status EnQueue(LinkQueue &Q, QElemType e); // 入队 Status EnQueue(LinkQueue& Q, QElemType e);//入队
Status DeQueue(LinkQueue &Q, QElemType &e); // 出队 Status DeQueue(LinkQueue& Q, QElemType& e);//出队
int QueueLength(LinkQueue Q); // 返回队列的长度 int QueueLength(LinkQueue Q);//返回队列的长度
Status GetHead(LinkQueue Q, QElemType &e); // 获取队头元素 注:由于参数个数不同,发生函数重载 Status GetHead(LinkQueue Q, QElemType& e);//获取队头元素 注:由于参数个数不同,发生函数重载
Status QueueEmpty(LinkQueue Q); // 判断队列是否为空 Status QueueEmpty(LinkQueue Q);//判断队列是否为空
void PrintQueue(); // 打印队列 void PrintQueue();//打印队列
Status QueueTraverse(LinkQueue Q); // 遍历队列Q  Status QueueTraverse(LinkQueue Q);//遍历队列Q 
/* /*
@ -77,301 +78,294 @@ Status QueueTraverse(LinkQueue Q); // 遍历
int main() int main()
{ {
srand((unsigned)time(NULL)); // 设定随机数种子 srand((unsigned)time(NULL));//设定随机数种子
printf("请输入银行的营业时间(min)"); printf("请输入银行的营业时间(min)");
scanf("%d", &CloseTime); scanf("%d", &CloseTime);
Bank_Simulation(CloseTime); Bank_Simulation(CloseTime);
return 0; return 0;
} }
void Bank_Simulation(int CloseTime) // 银行业务模拟,统计一天内客户在银行逗留的平均时间 void Bank_Simulation(int CloseTime)//银行业务模拟,统计一天内客户在银行逗留的平均时间
{ {
OpenForDay(); // 开始营业 OpenForDay();//开始营业
LNode *p; LNode* p;
while (!ListEmpty(ev)) while (!ListEmpty(ev))
{ {
DelFirst(GetHead(ev), p); DelFirst(GetHead(ev), p);
printf("********action********\n"); printf("********action********\n");
en = GetCurElem(p); en = GetCurElem(p);
if (en.NType == 0) if (en.NType == 0)
{ {
CustomerArrived(); CustomerArrived();
} }
else else
{ {
CustomerDepature(); CustomerDepature();
} }
PrintQueue(); PrintQueue();
PrintEventList(); PrintEventList();
} }
printf("The Average Time is %f\n", (float)TotalTime / CustomerNum); printf("The Average Time is %f\n", (float)TotalTime / CustomerNum);
} }
int cmp(Event a, Event b) // 比较事件发生先后 int cmp(Event a, Event b)//比较事件发生先后
{ {
if (a.OccurTime > b.OccurTime) if (a.OccurTime > b.OccurTime) return 1;
return 1; if (a.OccurTime = b.OccurTime) return 0;
if (a.OccurTime = b.OccurTime) if (a.OccurTime < b.OccurTime) return -1;
return 0;
if (a.OccurTime < b.OccurTime)
return -1;
} }
void OpenForDay() // 银行开门 void OpenForDay()//银行开门
// 初始化操作 //初始化操作
{ {
TotalTime = 0; // 初始化累计时间为0 TotalTime = 0;//初始化累计时间为0
CustomerNum = 0; // 初始化客户数为0 CustomerNum = 0;//初始化客户数为0
InitList(ev); // 初始化事件链表为空表 InitList(ev);//初始化事件链表为空表
en.OccurTime = 0; en.OccurTime = 0;
en.NType = 0; // 设定第一个客户到达事件 en.NType = 0;//设定第一个客户到达事件
OrderInsert(ev, en, cmp); OrderInsert(ev, en, cmp);
for (int i = 1; i <= 4; i++) for (int i = 1; i <= 4; i++)
{ {
InitQueue(q[i]); // 将四个银行窗口队列初始化 InitQueue(q[i]);//将四个银行窗口队列初始化
} }
} }
void OrderInsert(EventList L, Event en, int (*cmp)(Event a, Event b)) // 插入事件 void OrderInsert(EventList L, Event en, int(*cmp)(Event a, Event b))//插入事件
// 事件插入函数,将不同事件按发生时间递增排序 //事件插入函数,将不同事件按发生时间递增排序
{ {
LNode *p = L; LNode* p = L;
int i = 1; int i = 1;
while (p->next && cmp(en, p->next->data) > 0) // 找到事件发生时间所在事件链表中的位置 while (p->next && cmp(en, p->next->data) > 0)//找到事件发生时间所在事件链表中的位置
{ {
p = p->next; p = p->next;
i++; i++;
} }
ListInsert_L(ev, i, en); // 插入该事件 ListInsert_L(ev, i, en);//插入该事件
} }
void CustomerArrived() // 客户进门 void CustomerArrived()//客户进门
// 处理客户到达事件en.NType=0 //处理客户到达事件en.NType=0
{ {
CustomerNum++; CustomerNum++;
int durtime = rand() % 30 + 1; // 客户处理事务时间 int durtime = rand() % 30 + 1;//客户处理事务时间
int intertime = rand() % 8; // 下一个客户到达的时间间隔 int intertime = rand() % 8;//下一个客户到达的时间间隔
int t = en.OccurTime + intertime; // 下一个客户到达的时刻 int t = en.OccurTime + intertime;//下一个客户到达的时刻
if (t < CloseTime) // 如果他在营业时间内进来 if (t < CloseTime)//如果他在营业时间内进来
{ {
printf("一个新客户在银行营业%2dmin后进来办理业务花费了%2dmin下一个客户过了%2dmin后进来\n", en.OccurTime, durtime, intertime); printf("一个新客户在银行营业%2dmin后进来办理业务花费了%2dmin下一个客户过了%2dmin后进来\n", en.OccurTime, durtime, intertime);
OrderInsert(ev, {t, 0}, cmp); // 插入客户进门事件NType=0为到达事件 OrderInsert(ev, { t, 0 }, cmp);//插入客户进门事件NType=0为到达事件
} }
int i = Minimum(q); // 客户找最短队开始排队 int i = Minimum(q);//客户找最短队开始排队
EnQueue(q[i], {en.OccurTime, durtime}); EnQueue(q[i], { en.OccurTime, durtime });
if (QueueLength(q[i]) == 1) if (QueueLength(q[i]) == 1)
{ {
OrderInsert(ev, {en.OccurTime + durtime, i}, cmp); // 队列长度为1时设定一个离开事件 OrderInsert(ev, { en.OccurTime + durtime,i }, cmp);//队列长度为1时设定一个离开事件
}
} }
}
void CustomerDepature() // 客户离开 void CustomerDepature()//客户离开
{ {
int i = en.NType; int i = en.NType;
DeQueue(q[i], customer); // 删除第i队列的排头客户 DeQueue(q[i], customer);//删除第i队列的排头客户
TotalTime += en.OccurTime - customer.ArrivalTime; // 累计客户逗留时间 TotalTime += en.OccurTime - customer.ArrivalTime;//累计客户逗留时间
if (!QueueEmpty(q[i])) if (!QueueEmpty(q[i])) {
{ GetHead(q[i], customer);
GetHead(q[i], customer); OrderInsert(ev, { en.OccurTime + customer.Duration, i }, cmp);//插入事件
OrderInsert(ev, {en.OccurTime + customer.Duration, i}, cmp); // 插入事件 }
}
} }
int Minimum(LinkQueue Q[5]) // 求长度最短队列
{ int Minimum(LinkQueue Q[5])//求长度最短队列
int minLength = QueueLength(Q[1]); {
int i = 1; int minLength = QueueLength(Q[1]);
for (int j = 2; j < 5; j++) int i = 1;
{ for (int j = 2; j < 5; j++)
if (minLength > QueueLength(Q[j])) {
{ if (minLength > QueueLength(Q[j]))
minLength = QueueLength(Q[j]); {
i = j; minLength = QueueLength(Q[j]);
} i = j;
} }
return i;
} }
return i;
}
Status InitList(LinkList &L) // 链表初始化 Status InitList(LinkList& L)//链表初始化
{ {
L = (LinkList)malloc(sizeof(LNode)); L = (LinkList)malloc(sizeof(LNode));
if (!L) if (!L)
{ {
exit(OVERFLOW); exit(OVERFLOW);
} }
L->next = NULL; L->next = NULL;
return OK; return OK;
} }
Status ListInsert_L(LinkList &L, int i, ElemType e) // 在第i个位置之前插入元素e Status ListInsert_L(LinkList& L, int i, ElemType e)//在第i个位置之前插入元素e
{ {
LinkList p = L; LinkList p = L;
int j = 0; int j = 0;
while (p && j < i - 1) // 注意是i-1,因为要找被插入元素的前一个元素 while (p && j < i - 1)//注意是i-1,因为要找被插入元素的前一个元素
{ {
p = p->next; p = p->next;
j++; j++;
} }
if (!p || j > i - 1) if (!p || j > i - 1)
{ {
return ERROR; return ERROR;
} }
LinkList s = (LinkList)malloc(sizeof(LNode)); LinkList s = (LinkList)malloc(sizeof(LNode));
if (!s) if (!s)
{ {
exit(OVERFLOW); exit(OVERFLOW);
} }
s->data = e; s->data = e;
s->next = p->next; s->next = p->next;
p->next = s; p->next = s;
return OK; return OK;
} }
Status ListEmpty(LinkList L) // 判断链表是否为空 Status ListEmpty(LinkList L)//判断链表是否为空
// 空表头指针和头结点仍然存在但头结点指向NULL //空表头指针和头结点仍然存在但头结点指向NULL
{ {
if (L->next) if (L->next)
{ {
return FALSE; return FALSE;
} }
else else
{ {
return TRUE; return TRUE;
} }
} }
Status DelFirst(LinkList L, LNode *&q) // 删除链表中第一个结点并以q返回 Status DelFirst(LinkList L, LNode*& q)//删除链表中第一个结点并以q返回
{ {
if (!L->next) if (!L->next)
{ {
return ERROR; return ERROR;
} }
q = L->next; q = L->next;
L->next = q->next; L->next = q->next;
return OK; return OK;
} }
LNode *GetHead(LinkList L) // 返回链表头结点 LNode* GetHead(LinkList L)//返回链表头结点
{ {
return L; return L;
} }
ElemType GetCurElem(LNode *p) // 已知p指向线性链表中的一个结点返回p所指结点中元素的值 ElemType GetCurElem(LNode* p)//已知p指向线性链表中的一个结点返回p所指结点中元素的值
{ {
return p->data; return p->data;
} }
void PrintEventList() // 打印事件链表  void PrintEventList()//打印事件链表 
{ {
printf("Current Eventlist is:\n"); printf("Current Eventlist is:\n");
ListTraverse(ev); ListTraverse(ev);
} }
Status ListTraverse(LinkList &L) // 遍历链表   Status ListTraverse(LinkList& L) //遍历链表  
{ {
LNode *p = L->next; LNode* p = L->next;
if (!p) if (!p) {
{ printf("List is empty.\n");
printf("List is empty.\n"); return ERROR;
return ERROR; }
}
while (p != NULL) while (p != NULL) {
{ printf("OccurTime:%d,Event Type:%d\n", p->data.OccurTime, p->data.NType);
printf("OccurTime:%d,Event Type:%d\n", p->data.OccurTime, p->data.NType); p = p->next;
p = p->next; }
} printf("\n");
printf("\n"); return OK;
return OK;
} }
Status InitQueue(LinkQueue &Q) // 链队列的初始化
{
Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode)); Status InitQueue(LinkQueue& Q)//链队列的初始化
if (!Q.front) {
{ Q.front = Q.rear = (QueuePtr)malloc(sizeof(QNode));
exit(OVERFLOW); if (!Q.front)
} {
Q.front->next = NULL; exit(OVERFLOW);
return OK; }
} Q.front->next = NULL;
Status EnQueue(LinkQueue &Q, QElemType e) // 入队 return OK;
{ }
QNode *p = (QueuePtr)malloc(sizeof(QNode)); Status EnQueue(LinkQueue& Q, QElemType e)//入队
if (!p) {
{ QNode* p = (QueuePtr)malloc(sizeof(QNode));
exit(OVERFLOW); if (!p)
} {
p->data = e; exit(OVERFLOW);
p->next = NULL; }
Q.rear->next = p; p->data = e;
Q.rear = p; p->next = NULL;
return OK; Q.rear->next = p;
} Q.rear = p;
Status DeQueue(LinkQueue &Q, QElemType &e) // 出队 return OK;
{ }
if (Q.front == Q.rear) Status DeQueue(LinkQueue& Q, QElemType& e)//出队
{ {
return ERROR; if (Q.front == Q.rear)
} {
QNode *p = Q.front->next; return ERROR;
e = p->data; }
Q.front->next = p->next; QNode* p = Q.front->next;
if (Q.rear == p) // 注意这里要考虑到,当队列中最后一个元素被删后,队列尾指针也丢失了,因此需对队尾指针重新复制(指向头结点) e = p->data;
{ Q.front->next = p->next;
Q.rear = Q.front; if (Q.rear == p)//注意这里要考虑到,当队列中最后一个元素被删后,队列尾指针也丢失了,因此需对队尾指针重新复制(指向头结点)
} {
free(p); Q.rear = Q.front;
return OK; }
free(p);
return OK;
} }
int QueueLength(LinkQueue Q) // 返回队列的长度 int QueueLength(LinkQueue Q)//返回队列的长度
{ {
int count = 0; int count = 0;
QNode *p = Q.front->next; QNode* p = Q.front->next;
while (p) while (p) {
{ p = p->next;
p = p->next; count++;
count++; }
} return count;
return count;
} }
Status GetHead(LinkQueue Q, QElemType &e) // 获取队头元素 Status GetHead(LinkQueue Q, QElemType& e)//获取队头元素
{ {
if (Q.front == Q.rear) if (Q.front == Q.rear)
{ { return ERROR;}
return ERROR; e = Q.front->next->data;
} }
e = Q.front->next->data; Status QueueEmpty(LinkQueue Q)//判断队列是否为空
} {
Status QueueEmpty(LinkQueue Q) // 判断队列是否为空 if (Q.front == Q.rear)
{ {
if (Q.front == Q.rear) return TRUE;
{ }
return TRUE; return FALSE;
} }
return FALSE; void PrintQueue()//打印队列
} {
void PrintQueue() // 打印队列 //打印当前队列  
{ int i;
// 打印当前队列   for (i = 1; i <= 4; i++) {
int i; printf("窗口 %d 有 %d 个客户:", i, QueueLength(q[i]));
for (i = 1; i <= 4; i++) QueueTraverse(q[i]);
{ }
printf("窗口 %d 有 %d 个客户:", i, QueueLength(q[i])); printf("\n");
QueueTraverse(q[i]); }
} Status QueueTraverse(LinkQueue Q)//遍历队列Q  
printf("\n"); {
} QNode* p = Q.front->next;
Status QueueTraverse(LinkQueue Q) // 遍历队列Q   if (!p) {
{ printf("--Is empty.\n");
QNode *p = Q.front->next; return ERROR;
if (!p) }
{ while (p) {
printf("--Is empty.\n"); printf("(到达时刻 %d min 办理业务需要花费 %d min) ", p->data.ArrivalTime, p->data.Duration);
return ERROR; p = p->next;
} }
while (p) printf("\n");
{ return OK;
printf("(到达时刻 %d min 办理业务需要花费 %d min) ", p->data.ArrivalTime, p->data.Duration);
p = p->next;
}
printf("\n");
return OK;
} }

Binary file not shown.
Loading…
Cancel
Save