3.4队列
栈:先进后出,LIFO;
队列:先进先出,FIFO;队尾,rare,队头,front;
//队列的抽象数据定义
ADT queue{
数据对象:D = {ai | ai 属于Elemset}
数据关系:R1 = {<ai , ai-1>}
基本操作:初始化,销毁,清空,判空, 求长度,获得队头, 插入元素,删除队头并返回,调用函数;
}ADT queue
双端队列:端点1 , 端点2
受限的双端队列;
队列的两种表示:链队列
链队列的表示与实现:
typedef struct qnode{
qelemtype data;
struct qnode * next;
}qnode , queue;
typedef struct {
链队列的实现与类似问题;
循环队列:队列的顺序表示及实现
front与rare的位置;
循环队列解决判空问题的两种方法:另设一个标志位,少用一个元素空间并进行约定;
循环队列往往需要一个最大长度。如果无法预估,多采用链式存储结构;
循环队列的模块说明;
3.5 离散事件模拟
银行业务的模拟程序:
事件驱动模拟:整个模拟程序按照事件发生的先后顺序进行模拟;
算法:写出一个解决问题大致的算法;
程序的实现:需要的数据结构及操作
如何模拟问题:
根据时间主线来模拟问题:
1 根据当前时间处理用户,计算平均时间;
2 当前时间最小单元多大,可以根据业务处理的最小单元去考虑;
3 每一个最小单元,遍历用户表(提前根据随机数生成),判断是否有用户来以及是否有用户办理完了事情;
4 是极为复杂的;
5 以用户为主线模拟问题。
6 用户的到来是一个一个来的,是单线程的,可以,但是注意用户还可以继续再分,三个事件;
7 以事件为主线;
8 如何生成用户,以时间为主线是在事先确定用户表,而离散时间模拟是每到一个用户就新增下一个用户;
9 离散事件的处理以事件为主线;
10 数据结构:
事件链表:每个元素是事件;事件包含类型,与发生的时刻;
队列:每一个窗口有一个队列,每一个队列的元素是用户,用户具有到达时间,办理业务所需要的时间;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10000
#define winows_num 4
// 链表的类型,有头的单链表
// 事件
typedef struct{
long occurtime;
int type ;
// type = 预计会有下一个用户到达;不等于0 , 正在办理业务;
}LElemType;
typedef LElemType Event;
typedef struct lnode{
Event data;
struct lnode *next;
}lnode , * linklist;
typedef linklist EventList;//
void BankSimulation(int closeTime); //银行模拟
void OpenForDay(); //开店
void CloseForDay(); //关店
int GetMin(LinkQueue q[]); //得到人最少的窗口
void CustomerArriving(int closeTime); //预计用户到来
void CustomerDeparture(int closeTime); //用户离开
/***** 链表操作 ******/
void InitList(LinkList *pL);
int ListEmpty(LinkList L);
void OrderInsert(LinkList *pL, LElemType en);
void DelFirst(LinkList *pL, LElemType *e);
/***** 队列操作 ******/
void InitQueue(LinkQueue *Q);
int DelQueue(LinkQueue *pQ, QElemType *e);
int EnQueue(LinkQueue *pQ, QElemType e);
int QueueLength(LinkQueue Q);
int totalTime=0, customerNum=0; //累计客户逗留时间,客户数
EventList eventList; //事件表
Event event; //事件
CustomerQueue windows[WINDOWS_NUM+1]; //窗口,从1开始存储
Customer customer; //客户记录
int main(){
int closetime;
srand(time(NULL));
printf("输入营业的总分钟数:\n>>>");
scanf("%d" , &closetime);
banksimulation(closetime);
return 0;
}
//银行模拟
void banksimulation(int closetime){
openforday();
while(!ListEmpty(eventlist)){
DelFirst(&eventlist , &event);
if(event.type == 0){
customerarriving(closetime);
}
else{
customerdeparture(closetime);
}
}
closeforday();
}
//银行开门,初始化
void openforday(){
}
//
void closeforday(){
printf("\n客户数 = %d , 累计客户逗留时间 %d , 平均逗留时间 %d ,\n" , customernum , totaltime , totaltime/customernu);
}
// 预测用户到达事件
void customerarriving(int closetime){
long durtime;
long intertime;
int minwindow;
customernum ++ ;
printf("\t预测第%d名客户" , customernum);
//创建用户
durtime = rand()%15 + 1;
intertime = rand()%6;
customer.id = customernum;
customer.arrivaltime = event.occurtime + intertime;
customer.duration = durtime;
if(customer.arrivaltime > = closetime){
printf("\t× 生成的下一个用户将在第%dmin到达,那时候已经关门了\n", customer.arrivalTime);
}
}
/******链表操作***************/
// 有头节点的单链表
void InitList(LinkList *pl){
*pl = (lnode * )malooc(sizeof(lnode));
if(!*pl) exit(0);
(*pl)->next = NULL;
}
int ListEmpty(LinkList l){
return l - > next == NULL? 1 : 0
}
void DelFirst(Linklist *pl , LElemType *e){
lnode *p;
p = (*pl) - >next;
(*pl) - >next = p->next;
e - >occurtime = p->data.occurtime;
e-type = p-data.type;
free(p);
}