• 数据结构——银行排队模拟


      1 //离散事件模拟,模拟银行营业排队情况
      2 #include <stdio.h>
      3 #include <time.h>
      4 #include <stdlib.h>
      5 
      6 #define OK 1
      7 #define  ERROR 0
      8 #define TRUE 1
      9 #define FALSE 0
     10 
     11 typedef int Status;
     12 
     13 typedef struct Event{    //事件类型
     14     int OccurTime;        //事件发生时刻
     15     int NType;            //事件类型,0表示到达事件,1-4表示4个窗口离开事件
     16     struct Event *next;
     17 }Event,*ElemType;
     18 
     19 typedef struct{            //链表类型
     20     ElemType head;
     21     ElemType tail;
     22     int len;
     23 }LinkList;
     24 
     25 typedef LinkList EventList;        //事件链表
     26 
     27 typedef struct QElem{            //队列元素
     28     int ArrveTime;                //到达时间
     29     int Duration;                //办理事务所需事件
     30     struct QElem *next;
     31 }QElem,*QElemType;
     32 
     33 typedef struct{        //队列类型
     34     QElemType head;
     35     QElemType tail;
     36 }LinkQueue;
     37 
     38 Status InitList(LinkList *L);    //初始化事件链表
     39 Status OrderInsert(LinkList *L, Event e);    //将事件e按时间顺序插入有序链表L中
     40 Status ListEmpty(LinkList *L);    //判断链表为空,为空返回TRUE
     41 Status DelFirst(LinkList *L,ElemType e);    //删除链表首结点,用e返回
     42 Status ListTraverse(LinkList *L);    //遍历链表
     43 
     44 Status InitQueue(LinkQueue *Q);        //初始化队列
     45 Status EmptyQueue(LinkQueue *Q);    //判断队列为空
     46 Status DelQueue(LinkQueue *Q, QElemType e);    
     47 Status EnQueue(LinkQueue *Q, QElem e);    //接点e插入队列
     48 int       QueueLength(LinkQueue Q);
     49 Status GetHead(LinkQueue *Q, QElemType e);    //取队列首部结点e
     50 Status QueueTraverse(LinkQueue *Q);
     51 
     52 Event NewEvent(int occurTime, int nType);    //创建新事件
     53 
     54 int Min(int a[], int n);    //返回长度为n的数组a[]第一个最小下标,从1开始
     55 int ShortestQueue();        //获取最短队列编号
     56 void OpenForDay();            //初始化操作
     57 void CustomerArriver();        //顾客到达事件
     58 void CustomerDeparture();    //顾客离开事件
     59 void Bank_Simulation();        //银行排队模拟
     60 void PrintEventList();        //输出事件列表
     61 void PrintQueue();            //打印当前队列
     62 
     63 EventList ev;
     64 Event en;
     65 LinkQueue q[5];
     66 QElem customer;
     67 int TotalTime, CustomerNum;
     68 int CloseTime = 50;
     69 
     70 //----------------------main()--------------------//
     71 int main()
     72 {
     73     Bank_Simulation();
     74     return 0;
     75 }
     76 
     77 //-----------------------模拟排队----------------//
     78 void OpenForDay()
     79 {
     80     int i;
     81     TotalTime = 0; 
     82     CustomerNum = 0;
     83     InitList(&ev);
     84     en.OccurTime = 0;
     85     en.NType = 0;
     86     OrderInsert(&ev, en);
     87     for (i = 1; i < 5; i++)
     88         InitQueue(&q[i]);
     89 }
     90 
     91 void CustomerArrived() 
     92 {
     93     int durtime, intertime, i, t;
     94     QElem e;
     95     ++CustomerNum;
     96     intertime = rand() % 5 + 1;
     97     durtime = rand() % 30 + 1;
     98     t = en.OccurTime + intertime;
     99     if (t < CloseTime)
    100     {
    101         printf("A new customer will arrive at:%d
    ", t);
    102         OrderInsert(&ev, NewEvent(t, 0));
    103         i = ShortestQueue();
    104         e.ArrveTime = en.OccurTime;
    105         e.Duration = durtime;
    106         EnQueue(&q[i], e);
    107         if (QueueLength(q[i]) == 1)
    108             OrderInsert(&ev, NewEvent(en.OccurTime + durtime, i));
    109     }
    110 }
    111 
    112 void CustomerDeparture() 
    113 {    
    114     int i = en.NType;
    115     DelQueue(&q[i], &customer);
    116     printf("A customer leaves at:%d
    ", en.OccurTime);
    117     TotalTime += en.OccurTime - customer.ArrveTime;
    118     if (!EmptyQueue(&q[i]))
    119     {
    120         GetHead(&q[i], &customer);
    121         OrderInsert(&ev, NewEvent(en.OccurTime + customer.Duration, i));
    122     }
    123 }
    124 
    125 void Bank_Simulation()
    126 {
    127     OpenForDay();
    128     srand((unsigned)time(NULL));
    129     while(!ListEmpty(&ev)) {
    130         DelFirst(&ev, &en);
    131         if (en.NType == 0)
    132             CustomerArrived();
    133         else
    134             CustomerDeparture();
    135         PrintQueue();
    136     }
    137     printf("
    Total time is:%d min,average time is: %g min.
    ",TotalTime,
    138         (float)TotalTime/CustomerNum);
    139 }
    140 
    141 void PrintQueue()
    142 {
    143     int i;
    144     for ( i = 1; i < 5; i ++)
    145     {
    146         printf("Queue %d have %d customer(s):", i, QueueLength(q[i]));
    147         QueueTraverse(&q[i]);
    148     }
    149     printf("
    ");
    150 }
    151 
    152 void PrintEventList() 
    153 {
    154     printf("Current Eventlist is:
    ");
    155     ListTraverse(&ev);
    156 }
    157 
    158 int Min(int a[], int n)
    159 {
    160     int i, tmp, ind = 0;
    161     tmp = a[0];
    162     for (i = 1; i < n; i ++)
    163         if (a[i] < tmp)
    164         {
    165             tmp = a[i];
    166             ind = i;
    167         }
    168     return ind;
    169 }
    170 
    171 int ShortestQueue()
    172 {
    173     int i, a[4];
    174     for(i = 1; i <= 4; i++)
    175         a[i-1] = QueueLength(q[i]);
    176     return Min(a, 4) + 1;
    177 }
    178 
    179 //------------------------队和栈表操作-------------------//
    180 Event NewEvent(int occurT, int nType)
    181 {
    182     Event e;
    183     e.OccurTime = occurT;
    184     e.NType = nType;
    185     return e;
    186 }
    187 
    188 Status InitList(LinkList *L)
    189 {
    190     L->head = L->tail = (ElemType)malloc(sizeof(Event));
    191     if (!L->head) 
    192     {
    193         printf("Apply for memory error.LinkList initializefailed.
    ");
    194         exit(0);
    195     }
    196 
    197     L->head->next = NULL;
    198     return OK;
    199 }
    200 
    201 Status OrderInsert(LinkList *L, Event e)
    202 {
    203     ElemType p, q, newptr;
    204     newptr = (ElemType)malloc(sizeof(Event));
    205     if(!newptr)
    206     {
    207         printf("Apply for memory error.
    ");
    208         exit(0);
    209     }
    210     *newptr = e;
    211     if (TRUE == ListEmpty(L))
    212     {
    213         L->head->next = newptr;
    214         L->tail = newptr;
    215         L->tail->next = NULL;
    216         return OK;
    217     }
    218     q = L->head;
    219     p = L->head->next;
    220     while(p)
    221     {
    222         if (p->OccurTime >= newptr->OccurTime)
    223             break;
    224         q = p;
    225         p = p->next;
    226     }
    227     q->next = newptr;
    228     newptr->next = p;
    229     if (!p)
    230         L->tail = newptr;
    231     return OK;
    232 }
    233 
    234 Status ListEmpty(LinkList *L)
    235 {
    236     if((L->head == L->tail) && (L->head != NULL))
    237         return TRUE;
    238     else
    239         return FALSE;
    240 }
    241 
    242 Status DelFirst(LinkList *L, ElemType e)
    243 {
    244     ElemType p = L->head->next;
    245     if (!p)
    246         return ERROR;
    247     L->head->next = p->next;
    248     *e = *p;
    249     free(p);
    250     if (L->head->next == NULL)
    251         L->tail = L->head;
    252     return OK;
    253 }
    254 
    255 Status ListTraverse(LinkList *L)
    256 {
    257     ElemType p = L->head->next;
    258     if (!p)
    259     {
    260         printf("List is empty.
    ");
    261         return ERROR;
    262     }
    263     while (p)
    264     {
    265         printf("OccurTime:%d, Event Type:%d
    ", p->OccurTime, p->NType);
    266         p = p->next;
    267     }
    268     printf("
    ");
    269     return OK;
    270 }
    271 
    272 Status InitQueue(LinkQueue *Q)
    273 {
    274     Q->head = Q->tail = (QElemType)malloc(sizeof(QElem));
    275     if (!Q->head)
    276     {
    277         printf("Apply for memory error.LinkQueue initialize failed.
    ");
    278         exit(0);
    279     }
    280     Q->head->next = NULL;
    281     return OK;
    282 }
    283 
    284 Status EmptyQueue(LinkQueue *Q)
    285 {
    286     if ((Q->head == Q->tail) && (Q->head != NULL))
    287         return TRUE;
    288     else
    289         return FALSE;
    290 }
    291 
    292 Status DelQueue(LinkQueue *Q, QElemType e)
    293 {
    294     QElemType p = Q->head->next;
    295     if (!p)
    296         return    ERROR;
    297     *e = *p;
    298     Q->head->next = p->next;
    299     free(p);
    300     if (!Q->head->next)
    301         Q->tail = Q->head;
    302     return OK;
    303 }
    304 
    305 Status EnQueue(LinkQueue *Q, QElem e)
    306 {
    307     QElemType p = (QElemType)malloc(sizeof(QElem));
    308     if (!p)
    309     {
    310         printf("Apply for memory error, new element can't enqueue.
    ");
    311         exit(0);
    312     }
    313     *p = e;
    314     p->next = NULL;
    315     Q->tail->next = p;
    316     Q->tail = p;
    317     return OK;
    318 }
    319 
    320 int QueueLength(LinkQueue Q)
    321 {
    322     int count = 0;
    323     QElemType p = Q.head->next;
    324     while(p)
    325     {
    326         count ++;
    327         p = p->next;
    328     }
    329     return count;
    330 }
    331 
    332 Status GetHead(LinkQueue *Q, QElemType e)
    333 {
    334     if (EmptyQueue(Q))
    335         return ERROR;
    336     e = Q->head->next;
    337     return OK;
    338 }
    339 
    340 Status QueueTraverse(LinkQueue *Q)
    341 {
    342     QElemType p = Q->head->next;  
    343     if(!p){  
    344         printf("--Is empty.
    ");  
    345         return ERROR;  
    346     }  
    347     while(p){  
    348         printf("(%d,%d) ",p->ArrveTime,p->Duration);  
    349         p = p->next;  
    350     }  
    351     printf("
    ");  
    352     return OK;  
    353 }
  • 相关阅读:
    Android中Scrollview、ViewPager冲突问题汇总(已解决)
    Android 关于ZXing的使用
    startActivityForResult用法详解
    SVN的使用(服务端与客户端)
    Genymotion安装常见问题
    Android Viewpager实现图片轮播(仿优酷效果)
    Android Shape 详解
    Android apktool反编译资源文件为空解决办法(测试天猫、淘宝等apk成功)
    查看CentOS版本
    新建git仓库并与github同步
  • 原文地址:https://www.cnblogs.com/gjfhopeful/p/3601296.html
Copyright © 2020-2023  润新知