数据结构与算法--银行排队事件程序

#include <stdio.h>
#include <stdlib.h>
typedef struct evnode{
    int occurTime; //事件发生事件
    int nType;//事件类型,-1表示到达事件,0-3表示四个窗口的离开事件
    struct evnode * next;//指针域
}evNode,*Evenlist;
typedef struct clinet{//定义银行客户
    int arrivalTime;//客户到达银行的时间
    int duration;//办理业务所需时间
}Client;
typedef struct Node{//定义队列结点类型
    Client data;
    struct Node * next;
}Node,*Queueptr;
typedef struct {//定义队列类型
    Queueptr front,rear;
    int length;
}LinkQueue;
void CreateEventlist(Evenlist *L);//创建链表
int EmptyList(Evenlist L);//空为0,不空为1
void addNode(Evenlist *L, int a, int b);//有序插入链表,a表示事件发生事件,b表示窗口值
void delete(Evenlist *L,evNode * evltem);//删除首结点,并返回首节点的nType值
void displayNode(Evenlist L);//打印链表
void createLinkQueue(LinkQueue *Q);//创建链式队列
void enQueue(LinkQueue *Q,int a, int b);//入队,a表示客户到达银行的时间,b表示办理业务所需时间
int deQueue(LinkQueue *Q,int * a);//a为客户的服务时间
void getFront(LinkQueue *Q,Queueptr p);//若该队列不止一个人,前一个人离开之后需要计算下一个人的事件时间插入链表
int EmptyQueue(LinkQueue Q);//空为0,不空为1
void clearQueue(LinkQueue * Q);//清空队列
void displayQueue(LinkQueue *Q);//显示队列内容
int findmin(LinkQueue queue[],int size);//求最短队列
int main(void){
    int clientNumber = 0;//客户人数
    int totalTime = 0;
    int COST_TIME =100;//假设银行一天的服务时间
    LinkQueue queue[4];
    int durTime,interTime;
    Evenlist L = NULL;
    CreateEventlist(&L);
    int x = 0;
    int y = -1;//向链表中加入第一个元素
    addNode(&L,x,y);
    int j;
    for(j = 0; j < 4; j++){
        clearQueue(&queue[j]);
    };
    while(EmptyList(L)){//当事件不为空时
        evNode *evltem;
        delete(&L,evltem);//将事件队头元素删除并将其值赋予evltem变量
        if(evltem->nType == -1){
            //新客户到达事件
            clientNumber++;
            durTime = rand();//当前客户的服务时间
            interTime = rand();//下一个客户间隔多少时间到来
            if(evltem->occurTime + interTime < COST_TIME){//如果下一个客户到来的时间小于银行的关门时间
                int m = -1;//客户的到来将导致下一个客户的到来
                int n = evltem->occurTime + interTime;//下一个客户到达的时间
                addNode(&L,m,n);//将下个客户的信息填入事件
                int min = findmin(queue,4);//找到最短的队列
                int time = evltem->occurTime;//将当前客户到来的时间填入队列
                int dur = durTime;//将当前客户的服务时间填入队列
                enQueue(&queue[min],time,dur);//将客户的信息插入最短的队列
                if(queue[min].length == 1){//如果当前队列只有刚插入的这个元素
                    int occ = evltem->occurTime + durTime;//将这个客户的离开时间加入事件
                    int nyte = min;
                    addNode(&L,occ,nyte);
                }
            }
        }
        else{
            //客户离开事件
            int win = evltem->nType;//获取当前离开的是哪个队列
            int total;
            deQueue(&queue[win],&total);//删除队头元素并将其服务事件赋予total
            totalTime += total;//算出总时间
            if(queue[win].length != 0){//如果当前队列删除队头元素之后仍有元素
                Queueptr p;
                getFront(&queue[win],p);//获取队头元素的值到p中
                int occur = p->data.arrivalTime + total;//将第一个元素的服务时间加上当前元素的到达时间作为事件发生的事件
                addNode(&L,occur,win);//将当前事件加入到事件中
            }
        }
    }
    int customertimes = clientNumber / totalTime;
    printf("%d",customertimes);
    return 0;
}
void CreateEventlist(Evenlist *L){
    *L = (Evenlist)malloc(sizeof(evNode));
    (*L)->next = NULL;
}
int EmptyList(Evenlist L){
    if(L->next == NULL)
        return 0;
    else
        return 1;
}
void addNode(Evenlist *L, int a, int b){
    evNode *p,*current,*pre;
    p = (Evenlist)malloc(sizeof(evNode));
    p->occurTime = a;
    p->nType = b;
    current = (*L)->next;
    pre = *L;
    while(current && p->occurTime > current->occurTime){
        pre = current;
        current = current->next;
    }
    p->next = current;
    pre->next = p;
}
void delete(Evenlist *L,evNode * evltem){
    evltem = (*L)->next;
    (*L)->next = evltem->next;
}
void displayNode(Evenlist L){
    evNode *p = L->next;
    while(p){
        printf("%d %d",p->occurTime,p->nType);
        p = p->next;
    }
}
void createLinkQueue(LinkQueue *Q){
    Q->front = Q->rear = (Queueptr) malloc(sizeof(Node));
    Q->front->next = NULL;
    Q->length = 0;
}
void enQueue(LinkQueue *Q,int a, int b){
    Node *p;
    p = (Queueptr)malloc(sizeof(Node));
    p->data.arrivalTime = a;
    p->data.duration = b;
    p->next = NULL;
    Q->rear->next = p;
    Q->rear = p;
    Q->length++;
}
int deQueue(LinkQueue *Q,int * a){
    if(Q->rear == Q->front)
        return 1;
    else{
        Node * p;
        p = Q->front->next;
        *a = p->data.duration;
        Q->front->next = p->next;
        if(Q->rear == p)
            Q->front = Q->rear;
        free(p);
        Q->length --;
        return 0;
    }
}
void getFront(LinkQueue *Q, Queueptr p){
    p = Q->front->next;
}
int EmptyQueue(LinkQueue Q){
    if(Q.length == 0)
        return 0;
    return 1;
}
void clearQueue(LinkQueue * Q){
    while(Q->front){
        Q->rear = Q->front->next;
        free(Q->front);
        Q->front = Q->rear;
    }
}
void displayQueue(LinkQueue *Q){
    Node * p;
    p = Q->front->next;
    while(p){
        printf("%d %d",p->data.duration,p->data.arrivalTime);
        p = p->next;
    }
}
int findmin(LinkQueue queue[],int size){
    int minIndex = 0;
    for(int j = 1; j < size; j++){
        if(queue[j].length < queue[minIndex].length)
            minIndex = j;
    }
    return minIndex;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值