求C语言银行排队系统

银行排队系统
主要内容:
设某银行有n个窗口开展对外接待业务,从银行开门起不断有客户开展业务。客户人数众多时需要选择窗口排队,实现取票进队、排队等待、叫号服务。系统的主要功能如下:
①客户到达银行时能拿到排队号码,并能知道需要等待的人数。如果是VIP客户直接进入VIP窗口,无须加入普通客户的等待;
②可查看每个银行窗口正在给几号客户办理业务;
③客户离开银行时,有评价窗口银行职员服务的平台。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define USE_TIME  30    //客户在银行停留的最大时间
#define NEXT_TIme 5     //下一个客户到达的最大间隔时间
 
typedef struct E_list   //有序表结点
{
    int cur_time;   /*记录当前时间*/
    int E_type;     /*记录事件类型*/
    struct E_list* next;    /*指针域*/
} E_List,*EvenList;
 
typedef struct Q_node   //队列结点
{
    int arrive_time;    /*记录客户达到时间*/
    int dur_time;       /*记录客户在银行停留时间*/
    struct Q_node* next; /*指针域*/
} Q_Node,*QueueNode;
 
typedef struct E_queue  //队列操作结构
{
    QueueNode front;    /*指向队首元素*/
    QueueNode rear;     /*指向队尾元素*/
    int length;         /*记录队列长度*/
} E_queue,*Win_Queue;
 
 
int totalTime;          /*记录总时间*/
int allcustomer;        /*记录客户数量*/
int closetime;          /*设置关闭时间*/
E_List ev;  //有序表头节点
E_queue e_q[4]; //窗口队列操作结构
 
 
void enter_List(EvenList new_E)    //进入有序表
{
    EvenList agent = ev.next;   //代理指针指向第一个元素
    EvenList pre_E =&ev;        //代理指针指向头结点
    while(agent!=NULL && (new_E->cur_time > agent->cur_time)) //找到元素的插入位置
    {
        pre_E = agent;
        agent = agent->next;
    }
    if(agent == NULL)   /*插入到表尾*/
    {
        pre_E->next = new_E;
    }
    else                /*插入到非表尾位置*/
    {
        new_E->next = agent;
        pre_E->next = new_E;
    }
    agent = ev.next;
    while(agent!=NULL)  /*进行表的遍历*/
    {
        printf("(%d,%d)\n",agent->cur_time,agent->E_type);
        agent = agent->next;
    }
    printf("\n\n");
}
void out_List(EvenList Event)                  //出有序表
{
    /*记录待删除结点的数据后,释放该结点*/
    EvenList temp = ev.next;
    Event->cur_time = temp->cur_time;
    Event->E_type = temp->E_type;
    Event->next = NULL;
    ev.next = temp->next;  //出有序表节点
    printf("%p\n",temp->next); //测试语句
    printf("待处理客户:(%d , %d)\n",temp->cur_time,temp->E_type); /*测试语句*/
    free(temp); /*释放待删除结点*/
 
}
void en_Queue(Win_Queue q, QueueNode new_node)        //进入指定队列
{
    /*将元素加入到队列末尾,并增加队列长度*/
    q->rear->next = new_node;
    q->rear = new_node;
    q->length++;
}
void DeQueue(Win_Queue q,QueueNode node)                          //出队列
{
    /*记录待出队列结点的数据,释放该结点后,队列长度减一*/
    QueueNode temp = q->front->next;
    q->front->next = temp->next;
    q->length--;        /*队列长度减一*/
    /*存储待删除结点的数据*/
    node->arrive_time = temp->arrive_time;
    node->dur_time = temp->dur_time;
    node->next = NULL;
}
 
void openforday()                               //初始化数据
{
    int i;
    EvenList temp;
    QueueNode temp_q;
    totalTime = 0;      /*初始化时间记录器*/
    allcustomer = 0;    /*初始化顾客记录器*/
    closetime = 5;      /*初始化银行关闭时间*/
    temp = (EvenList)malloc(sizeof(E_List));
    if(temp == NULL)
    {
        printf("memory is failure!\n");
        exit(1);
    }
    temp->cur_time = 0;
    temp->E_type = 0;
    temp->next = NULL;
    ev.next = temp; /*将第一个客户数据(0,0,)加入到事件表*/
    for(i=0; i<4; i++)  //为每一个窗口队列设置头节点
    {
        temp_q = (QueueNode)malloc(sizeof(Q_Node));
        if(temp_q == NULL)
        {
            printf("memory allocate is failure!\n");
            exit(1);
        }
        temp_q->next = NULL;
        e_q[i].front = temp_q;
        e_q[i].rear = temp_q;
        e_q[i].length = 0; /*初始化队列长度*/
    }
 
}
 
void Even_head(EvenList E)                       //得到有序表的第一个客户
{
    /*获得事件表第一个元素的副本*/
    E->cur_time = ev.next->cur_time;
    E->E_type = ev.next->E_type;
    E->next = NULL;
}
void arrive_Event()  //处理客户到达事件
{
    /**
    *系统产生两个随机数(x,y),x表示当前窗口type = 0的用户在银行的停留时间
    *y表示下一个客户与上一个客户的间隔时间。
    *如果新客户的当前时间在事件表允许的范围内,则变动事件表(记录新客户的到达事件和
    *前一位客户的离开事件和队列位置)
    *反之则只记录前一位客户的离开事件
    */
    int i,min = 0;
    QueueNode new_node; /*声明新的队列结点*/
    EvenList new_E1,new_E2;/*声明新的事件结点*/
    int next_time,use_time; /*随机数记录器*/
    use_time = rand()%USE_TIME; /*获得当前窗口客户的银行停留时间*/
    next_time = rand()%NEXT_TIme;/*获得下一位客户到达的间隔时间*/
 
    printf("产生随机数为(%d , %d)\n",use_time,next_time); //测试语句
 
 
 
 
    new_node = (QueueNode)malloc(sizeof(Q_Node));       //为队列结点分配空间
    new_E1 = (EvenList)malloc(sizeof(E_List));           //为有序表结点分配空间
    new_E2 = (EvenList)malloc(sizeof(E_List));
    if(new_node == NULL || new_E1 == NULL || new_E2 == NULL)    /*检查空间是否分配*/
    {
        printf("memory allocate is failure!\n");
        exit(1);
    }
 
    out_List(new_E2);       //取出头节点(此操作会删除原始结点)
    /*初始化队列结点*/
    new_node->arrive_time = new_E2->cur_time;
    new_node->dur_time = use_time;
    new_node->next = NULL;
    /*初始化有序表结点*/
    new_E1->cur_time = new_E2->cur_time+use_time;   //正在窗口的用户
    new_E1->next = NULL;
    new_E2->cur_time = new_E2->cur_time+next_time;    //新到达用户
    printf("closetime = %d\n",closetime);
    if((new_E2->cur_time)< closetime )  //满足事件则插入新客户
    {
        enter_List(new_E2);     //加入一次
    }
    for(i=1 ; i<4; i++)     /*获得最短队列*/
    {
        if(e_q[i].length<e_q[min].length)
        {
            min = i;
        }
    }
    new_E1->E_type = min+1; /*当前客户记录自己窗口号*/
    enter_List(new_E1);  //重新插入前一个客户的数据
    en_Queue(&e_q[min],new_node);//用户进入排队队列
    for(i=0 ; i<4; i++)     //测试语句(显示所有队列的长度)
    {
        printf("%4d\n",e_q[i].length);
    }
    printf("\n");
 
}
 
void leave_Event()   //处理客户离开事件
{
    Q_Node Qu_noe;
    E_List node;
    out_List(&node);    /*取出事件表第一个有效结点*/
    DeQueue(&e_q[node.E_type-1],&Qu_noe); /*将客户从指定队列位置取出*/
    /*开始累加客户在银行的停留时间和客户数量*/
    totalTime+=Qu_noe.dur_time;
    allcustomer++;
    //测试语句
    printf("有客户从%d窗口离开,在银行停留了%d分钟!\n",node.E_type,Qu_noe.dur_time);
}
int Isempty_E()        /*判断事件表是否为空*/
{
    if(ev.next == NULL)
    {
        return 1;
    }
    else
    {
        return 0;
    }
}
void Bank_simulation()     //银行模拟程序
{
    E_List temp;
    openforday();   /*初始化数据*/
    while(!Isempty_E()) /*事件表不为空则进行客户处理*/
    {
        Even_head(&temp);   /*得到第一个节点的副本*/
        if(temp.E_type == 0)    /*type = 0,处理客户到达事件*/
        {
            arrive_Event();
        }
        else
        {
            leave_Event();  /*处理客户离开事件*/
        }
 
    }
    printf("总共有%d客户,客户在银行停留总时间为:%d\n",allcustomer,totalTime);
    printf("The Average time is %f\n",(double)totalTime/allcustomer);
}
 
int main()
{
 
    srand(time(NULL));          //设置随机数种子
    printf("银行将在6点开始营业,下午18点结束!\n");
    printf("默认原数输入为(0, 0)\n");  /*第一个客户到达时间*/
    Bank_simulation();
}

去猪八戒上找外包吧。

自己翘着试试“