C语言数据结构之离散事件模拟的实现代码(银行排队事件)
C语言数据结构之离散事件模拟的实现代码(银行排队事件)
结果:
IDE:Visual Studio 2019
声明:为了方便书写代码,用到了C++的引用调用特性和iostream作为输入输出,读者可以使用指针调用和scanf_s/print语句实现相同效果
tips:有疑问可以在下面交流,我会尽量回复的
头文件heads.h
#pragma once
#include "stdio.h"
#include "iostream"
#include "time.h"
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OVERFLOW -1
typedef short int Status;
using namespace std;
//事件的结构体
typedef struct {
int Occurtime;
int NType;
}Event,ElemType;
//顾客的结构体
typedef struct {
int Arrivaltime;
int Duration;
}Customer, QElemType;
//窗口前的顾客
typedef struct LNode {
QElemType data;
struct LNode* next;
}LNode,*Link;
//窗口
typedef struct {
Link front, rear;
int len;
}Cust;
//事件表
typedef struct Node{
ElemType data;
struct Node* next;
}*LinkList,*Eventlist,Node;
//程序主要变量
Eventlist ev;
Event en;
Cust q[5];
QElemType customer;
int TotalTime, CustomerNum, durtime, intertime;
int CloseTime = 480;//关门时间
头文件LNode.h
带头结点的链表,用来作为事件表,熟悉链表操作的建议不看
#include"heads.h"
//1.表的初始化
Status InitLNode(LinkList& L) {
L = (LinkList)malloc(sizeof(LNode));
L->next = NULL;
return OK;
}//InitLNode
//2.销毁
Status DestoryLNode(LinkList& L) {
LinkList p, q = L->next;
while (q != NULL) {
p = q->next;
free(q);
q = p;
}
L->next = NULL;
return OK;
}//第一种写法
Status Destory(LinkList& L) {
LinkList p;
while (L->next != NULL) {
p = L->next;
L->next = p->next;
free(p);
}
L->next = NULL;
return OK;
}//第二种写法
Status Empty(LinkList L) {
return (L->next == NULL) ? TRUE : FALSE;
}
//5.返回表的长度
Status Length(LinkList L) {
int len = 0;
LinkList head = L->next;
while (head != NULL) {
head = head->next;
len++;
}
return len;
}
//6.查找第i个元素
Status GetDate(LinkList L, int i, ElemType& e) {
LinkList p = L;
for (; i > 0; i--) {
if (!p->next)return ERROR;
p = p->next;
}
e = p->data;
return OK;
}
//7.按值查找
Status Locate(LinkList L, int& i, ElemType e) {
i = 0;
int j = 0;
LinkList p, q = L;
while (q->next != NULL) {
p = q->next;
q = p;
i++;
j = (p->data.Occurtime == e.Occurtime) ? i : NULL;
}
if (!j)return ERROR;
return OK;
}
//8.按位置插入
Status InsertElem(LinkList& L, int i, ElemType e) {
LinkList p, q = L;
for (int j = 1; j < i; j++) {
if (!q->next && j > i - 1) break;
q = q->next;
}
p = (LinkList)malloc(sizeof(LNode));
p->next = q->next;
q->next = p;
p->data = e;
return OK;
}
//9.按位置删除
Status Delete(LinkList& L, int i, ElemType& e) {
LinkList q, p = L;
for (int j = 1; j < i; j++) {
if (!p->next)return ERROR;
p = p->next;
}
q = p->next;
p->next = p->next->next;
e = q->data;
free(q);
return OK;
}
//遍历事件表
Status Display(LinkList L) {
LinkList p = L;
while (1)
{
if (!p->next)break;
p = p->next;
cout <data.Occurtime << ",类型: "<data.NType<
}
return OK;
}
头文件basicfunctions.h
队列结构,存储窗口前顾客的队列,熟悉队列结构的可以不看
#include "heads.h"
//初始化顾客队列
Status InitQueue(Cust& Q) {
Link q = (Link)malloc(sizeof(LNode));
if (!q)return ERROR;
Q.front = q;
Q.rear = q;
Q.len = 0;
q->next = NULL;
return OK;
}
//清空顾客队列
Status ClearQueue(Cust& Q) {
if (Q.len == 0)return ERROR;
Link q = Q.front->next,p;
while (q); {
p = q;
q = q->next;
free(p);
}
Q.rear = Q.front;
Q.front->next = NULL;
Q.len = 0;
return OK;
}
//摧毁顾客队列
Status DestoryQueue(Cust& Q) {
ClearQueue(Q);
free(Q.front);
return OK;
}
//判空
Status QueueEmpty(Cust Q) {
if (Q.len == 0)return TRUE;
return FALSE;
}
//返回长度
int QueueLength(Cust Q) {
return Q.len;
}
//用e返回头元素
Status GetHead(Cust Q, QElemType& e) {
if (Q.len == 0)return ERROR;
e = Q.front->next->data;
return OK;
}
//入队列
Status EnQueue(Cust& Q, QElemType e) {
Link q = (Link)malloc(sizeof(LNode));
if (!q)return ERROR;
q->data = e;
q->next = NULL;
Q.rear->next = q;
Q.rear = q;
Q.len++;
return OK;
}
//出队列
Status DeQueue(Cust& Q, QElemType& e) {
if (Q.len == 0)return ERROR;
Link q = Q.front->next;
e = q->data;
Q.front->next = q->next;
free(q);
Q.len--;
if (Q.len == 0)Q.rear = Q.front;
return OK;
}
//顾客访问
Status visit(QElemType e) {
cout << "到达时间" << e.Arrivaltime << " 业务所需时间" << e.Duration << " ;";
return OK;
}
//顾客队列访问
Status QueueTraverse(Cust Q, Status(*visit)(QElemType)) {
Link q = Q.front->next;
while (q) {
visit(q->data);
q = q->next;
}
cout << endl;
return OK;
}
头文件Bank_Simulation.h
#include "basicfunctions.h"
#include "LNode.h"
//事件发生的时间比较
int cmp(Event a, Event b) {
if (a.Occurtime >= b.Occurtime)return 1;
return 0;
}
//四窗口前长度比较
int compare(int a, int b,int c,int d) {
if (a < b) {
if (a < c) {
if (a < d)return 1;
return 4;
}
if (c < d)return 3;
return 4;
}
if (b < c) {
if (b < d) return 2;
return 4;
}
if (c < d)return 3;
return 4;
}
int min(Cust c[]) {
return compare(c[1].len, c[2].len, c[3].len, c[4].len);
}
//随机生成6-25的durtime和1-10的intertime
Status Random(int &durtime, int &intertime) {
durtime = rand() % 20 + 6;
intertime = rand() % 10 + 1;
return OK;
}
//按发生时间插入事件表
Status OrderInsert(LinkList& L, Event e) {
Node *p = L, *q=(Node*)malloc(sizeof(Node));
if (!q)return OVERFLOW;
q->data = e;
while (p->next) {
if(cmp(p->next->data, q->data))break;
p = p->next;
}
q->next = p->next;
p->next = q;
return OK;
}
//一天的初始化
void OpenForDay() {
TotalTime = 0; CustomerNum = 0;
InitLNode(ev);
en.Occurtime = 0; en.NType = 0;
OrderInsert(ev, en);
for (int i = 1; i < 5; i++)InitQueue(q[i]);
}
//处理客户到达事件
void CustomerArriverd() {
Event e, f;
++CustomerNum;
Random(durtime, intertime);
int t = en.Occurtime + intertime;
if (t < CloseTime) {
e.Occurtime = t;
e.NType = 0;
OrderInsert(ev, e);
}
customer.Arrivaltime = en.Occurtime;
customer.Duration = durtime;
int i = min(q);
EnQueue(q[i], customer);
if (QueueLength(q[i]) == 1) {
f.Occurtime = en.Occurtime + durtime;
f.NType = i;
OrderInsert(ev, f);
}
Display(ev);
cout <
QueueTraverse(q[i], visit);
}
//处理客户离开事件
void CustomerDeparture() {
Event e;
int i = en.NType; DeQueue(q[i], customer);
TotalTime += en.Occurtime - customer.Arrivaltime;
if (!QueueEmpty(q[i])) {
GetHead(q[i], customer);
e.Occurtime = en.Occurtime + customer.Duration;
e.NType = i;
OrderInsert(ev, e);
}
}
//事件
void Simulation() {
OpenForDay();
while (ev->next) {
Delete(ev, 1, en);
if (en.NType == 0) {
CustomerArriverd();
}
else CustomerDeparture();
}
cout << "The Average Time is:" << (float)TotalTime / CustomerNum;
}
源文件main.cpp
#include "Bank_Simulation.h"
int main(void) {
srand((unsigned int)time(NULL));//取当前时间为随机数种子,确保多次运行的结果不一样
Simulation();
}
因为自己是一边想一边写的,所以注释写的不是很好,有不懂或者我有错误的地方欢迎大家指正。
C语言数据结构之离散事件模拟的实现代码(银行排队事件)相关教程
C语言一元二次方程求解问题
C语言一元二次方程求解问题 前几天我的数据结构老师帮我们补习C语言,出的这个问题。要求至少考虑到6种情况,用文件读写的方法,并且数据提前给定不再从键盘输入。 下面是我写的第一个版本: #includestdio.h#includestdlib.h#includewindows.h#define ARRAYL
2020秋季C语言练习题(4)
2020秋季C语言练习题(4) A. 党费 运行时间限制: 1000 运行内存限制: 65536 作者: bupt_admin 是否specialjudge: False 题目描述 题目描述 党费是党员向党组织交纳的用于党的事业和党的活动的经费。交纳党费是党员对党组织应尽的义务,是党员关心党的事业的
OJNOI1.802:同行列对角线的格子(C语言)
OJNOI1.802:同行列对角线的格子(C语言) 题目来源http://noi.openjudge.cn/ch0108/02/ 02:同行列对角线的格子 查看提交统计提问 总时间限制: 1000ms 内存限制: 65536kB 描述 输入三个自然数N,i,j (1=i=N,1=j=N),输出在一个N*N格的棋盘中(行列均从1开
RTMP协议视频直播点播平台EasyDSS内Go语言使用反射优化代码技巧
RTMP协议视频直播点播平台EasyDSS内Go语言使用反射优化代码技巧说明 在开发 EasyDSS 项目中,随着功能的扩大,慢慢的发现有很多类似的代码存在于代码中。因为结构体的不同,使用相同的函数进行合并非常困难,使用反射就可以将这些代码合并。 代码量越少,出现
数据结构学习C++:队
数据结构学习C++:队 队是一种线性表,它进队的一端是队尾,出队的一端是队头 由于队只能在队尾插入队元素,在队头删除队元素,所以先入队的元素可以先出队,后入队的元素后出队,所以队是先进先出表或者后进后出表 根据队的需求,首先是需要申请一组连续的内
C语言sizeof求结构体数组长度
C语言sizeof求结构体数组长度 #include stdio.htypedef struct ss{char a;//偏移量为0,大小为1,0能被1整除,=1short b;//偏移量为1,大小为2,1不能被2整除,=1+1+2=4int c;//偏移量为4,大小为4,4能被4整除,=4+4=8long d;//偏移量为8,大小为4,8能被4整除,
自学笔记:数据结构
自学笔记:数据结构 数据结构 ##2.1 数据结构 根据韩顺平老师的数据结构与算法视频学习的 包括: 线性结构 和 非线性结构 线性结构:最常用的数据结构。特点是数据与元素之间存在一对一关系,例如数组,队列,链表,栈等。按照存储结构又分为顺序存储结构和链
哈佛大学——差异表达分析(二)R语言复习
哈佛大学——差异表达分析(二)R语言复习 文章目录 DGE分析流程 R语言复习QA 学习目标 Setting up Creating vectors/factors and dataframes Exploring data Extracting data Visualizing data Preparing for downstream analysis tools DGE分析流程 理解在R