数据结构——队列(银行叫号系统)
生活随笔
收集整理的這篇文章主要介紹了
数据结构——队列(银行叫号系统)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數據結構——隊列(銀行叫號系統)
一、實驗目的
(1)掌握隊列的鏈式存儲結構
(2)掌握隊列的基本操作,并能進行應用實踐
(3)使用C/C++語言和隊列實現”銀行叫號系統“專題
二、實驗任務
設計一個控制臺程序,模擬銀行排隊業務,要求實現功能:
(1)輸出程序界面,提示客戶輸入銀行窗口數量和開放窗口時間
(2)客戶隨機時間進入銀行,程序在事件表中記錄客戶進入時間和離開時間,并將客戶排入窗口隊列,辦理完業務后退出隊列
(3)窗口開放時間結束,客戶停止進入銀行,直到所有客戶退出隊列之后計算出客戶的平均服務時間
三、實驗代碼
1.事件列表
1)定義事件結點
2)初始化事件鏈表
int InitList(EventList* pList)//初始化事件鏈表 {*pList=(Event*)malloc(sizeof(Event));if(*pList==NULL){printf("分配內存失敗\n");exit(-1);}(*pList)->next=NULL;return OK; }3)插入元素
int OrderInsert(EventList pList,Event sEvent)//插入元素 {Event *pAfter,*pBefore;//臨時變量,用于在鏈表中插入結點pAfter=pList;pBefore=pList->next;while(pAfter!=NULL && sEvent.occurTime>pAfter->occurTime)//比較事件發生的時間{pBefore=pAfter;pAfter=pAfter->next;}pBefore->next=(Event*)malloc(sizeof(Event));//創建一個新的結點,掛在Before和After兩個結點中間pBefore->next->occurTime=sEvent.occurTime;//對新結點賦值pBefore->next->type=sEvent.type;pBefore->next->next=pAfter;return OK; }4)判斷鏈表是否為空
int EmptyList(EventList pList)//判斷鏈表是否為空 {if(pList->next==NULL)return TRUE;elsereturn FALSE; }5)刪除首結點
int DelFirst(EventList pList,Event *pEvent)//刪除首結點 {Event *pTmp;if(EmptyList(pList)){printf("鏈表為空");return ERROR;}else {pTmp=pList->next;//刪除鏈表首結點pList->next=pTmp->next;*pEvent=*pTmp;//保存數值free(pTmp);//釋放內存return OK;} }6)遍歷鏈表
int ListTraverse(EventList pList)//遍歷鏈表 {Event *pTmp;pTmp=pList;while(pTmp->next!=NULL){pTmp=pTmp->next;if(pTmp->type==0)printf("第%d分鐘,下一名客戶即將到來。\n",pTmp->occurTime);elseprintf("第%d分鐘,%d號窗口的客戶即將離開。\n",pTmp->occurTime,pTmp->type);}printf("\n");return OK; }2.鏈式隊列
1)定義鏈式隊列數據結構
2)初始化隊列
int InitQueue(LinkedQueue *pQueue)//初始化隊列 {pQueue->front=pQueue->rear=(QElemType*)malloc(sizeof(QElemType));//分配內存if(pQueue->front==NULL){printf("分配內存失敗\n");exit(-1);}pQueue->front->next=NULL;return OK; }3)判斷鏈表是否為空
int EmptyQueue(LinkedQueue *pQueue)//判斷鏈表是否為空 {if(pQueue->front==pQueue->rear)return TRUE;else return FALSE; }4)首結點出隊
int DelQueue(LinkedQueue *pQueue,QElemType *pQElem)//首結點出隊 {QElemType *pTmp;//臨時結點指針if(EmptyQueue(pQueue)){printf("隊列為空,不能繼續出隊列\n");return ERROR;}else {//指向首結點后一個元素,并復制給pQElempTmp=pQueue->front->next;*pQElem=*pTmp;pQueue->front->next=pTmp->next;//刪除這個結點if(pQueue->rear==pTmp)pQueue->rear=pQueue->front;free(pTmp);return OK;} }5)結點入隊
int EnQueue(LinkedQueue *pQueue,QElemType sQElem)//結點入隊 {QElemType *pTmp;//臨時結點指針pTmp=(QElemType*)malloc(sizeof(QElemType));if(pTmp==NULL){printf("內存分配失敗\n");exit(-1);}else {//尾結點指向新入隊的元素*pTmp=sQElem;pTmp->next=NULL;pQueue->rear->next=pTmp;pQueue->rear=pTmp;}return OK; }6)獲取隊列長度
int QueueLength(LinkedQueue *pQueue)//獲取隊列長度 {QElemType *pTmp;//臨時結點指針int count=0;//遍歷鏈表,統計結點數pTmp=pQueue->front->next;//隊列第一個結點while(pTmp!=NULL){count++;pTmp=pTmp->next;}return count; }7)獲取隊列首結點
int GetHead(LinkedQueue *pQueue,QElemType *pQElem)//獲取隊列首結點 {if(EmptyQueue(pQueue)){printf("隊列為空");return ERROR;}*pQElem=*(pQueue->front->next);return OK; }8)遍歷隊列
int QueueTraverse(LinkedQueue *pQueue)//遍歷隊列 {QElemType *pTmp;//臨時結點指針if(EmptyQueue(pQueue)){printf("隊列為空\n");return ERROR;}pTmp=pQueue->front->next;//隊列第一個結點while(pTmp!=NULL){printf(">[到達時刻:第%d分鐘,服務時長:%d分鐘]\n",pTmp->arriveTime,pTmp->duration);pTmp=pTmp->next;}printf("\n");return OK; }3.主要業務功能
1)定義全局變量
2)初始化數據
void Initialize( )//初始化數據 {int i;gTotalTime=0;gCustomerNum=0;InitList(&gEventList);//初始化事件列表printf("請輸入銀行服務窗口個數(1~20):");//服務窗口個數scanf("%d",&gWindowsNum);while (gWindowsNum<1 || gWindowsNum>MAXSIZE){printf("請輸入1到%d之間的整數:",MAXSIZE);scanf("%d",&gWindowsNum);}printf("\n請輸入服務關閉時間(超過這個時間就不在接納新顧客)(單位:分鐘):");//服務關閉時間scanf("%d",&gCloseTime);while(gCloseTime<1){printf("請輸入大于零的整數:");scanf("%d",&gCloseTime);}for(i=0;i<gWindowsNum;i++)//為每個窗口建立一個空隊列{InitQueue(&gQueue[i]);} }3)處理客戶到達事件
int ShortestQueue( );void CustomerArrived()//處理客戶到達事件 {QElemType sQElem;Event sEvent;int index;//排隊人數最少的窗口編號int arrivetime;//客戶到達時間int duration;//業務辦理時間printf("當前時刻:第%d分鐘\n", gEvent.occurTime);//顧客到達的時間,在上一位顧客之后1~5分鐘arrivetime = gEvent.occurTime+ rand() % 5 + 1;duration = rand() % 21 + 10;//辦理業務時間為10~30分鐘if (arrivetime < gCloseTime)//服務尚未關閉{gCustomerNum++;//新顧客到達事件sEvent.occurTime = arrivetime;sEvent.type = 0;OrderInsert(gEventList, sEvent);//顧客進入人數最少的窗口排隊sQElem.arriveTime = gEvent.occurTime;//入隊時刻sQElem.duration = duration;//辦理業務時間index = ShortestQueue();EnQueue(&gQueue[index], sQElem);//入列//如果恰好排在了隊首,預定離開事件if (QueueLength(&gQueue[index]) == 1){//記錄顧客從第index+1號號窗口離開(因為索引從0開始)sEvent.occurTime =gEvent.occurTime + duration;sEvent.type = index + 1;OrderInsert(gEventList, sEvent);}}else//銀行排隊服務關閉,不再接受新客戶printf("\n排隊服務以關閉,不再接受新客戶!\n"); }4)處理顧客離開事件
void CustomerLeaved( )//處理顧客離開事件 {Event sEvent;int index=gEvent.type-1;//隊列編號為窗口編號-1DelQueue(&gQueue[index],&gCustomer);//刪除隊首結點printf("\n顧客離開時間:第%d分鐘。",gEvent.occurTime);gTotalTime+=gCustomer.duration;//記錄服務時間//如果隊列不為空,則預定下一位顧客從第index+1號窗口離開if(!EmptyQueue(&gQueue[index])){GetHead(&gQueue[index],&gCustomer);//獲得下一位顧客//記錄離開事件sEvent.occurTime=gEvent.occurTime+gCustomer.duration;sEvent.type=index+1;OrderInsert(gEventList,sEvent);} }5)獲取最短隊列的編號
int ShortestQueue( )//獲取最短隊列的編號 {int i=0;int min=9999;//最短隊列的長度int index=-1;//最短隊列的編號int length=0;//遍歷各個窗口,比較哪個窗口排隊的人最少for(i=0;i<gWindowsNum;i++){length=QueueLength(&gQueue[i]);if(min>length){min=length;index=i;}}return index; }6)顯示當前窗口隊列
void PrintQueue( )//顯示當前窗口隊列 {int i;printf("\n窗口排隊狀態:\n");for(i=0;i<gWindowsNum;i++){printf("%d號窗口:\n",i+1);QueueTraverse(&gQueue[i]);}printf("\n"); }7)顯示當前時間表
void PrintEventList( )//顯示當前時間表 {printf("\n事件表狀態:\n");ListTraverse(gEventList); }8)銀行排隊模擬
void BankSimulation( )//銀行排隊模擬 {//隨機數發生器,用于模擬隨機客戶排隊事件//根據當前系統時間初始化隨機種子srand( (unsigned)time(NULL));//準備開業Initialize( );//第一個顧客到來gEvent.occurTime=0;gEvent.type=0;OrderInsert(gEventList,gEvent);//處理排隊列表while(!EmptyList(gEventList)){DelFirst(gEventList,&gEvent);//處理顧客事件if(gEvent.type==0)CustomerArrived( );elseCustomerLeaved( );//顯示當前事件列表,以及排隊情況PrintEventList( );PrintQueue( );//暫停一會,便于觀察輸出內容system("PAUSE");printf("\n");}//平均服務時間printf("\n");printf("客戶平均服務時間:%f分鐘\n",(float)gTotalTime/gCustomerNum);system("PAUSE"); }4.主函數入口
#include<stdio.h> #include<malloc.h> #include<stdlib.h> #include<time.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -2 int main( )//主函數入口 {BankSimulation( );return 0; }5.程序運行截圖
**~~本 蒟蒻 發布的第一篇文章,貼代碼不易,復制后別忘了 點贊哦 (@W@)!,蟹蟹啦!*
總結
以上是生活随笔為你收集整理的数据结构——队列(银行叫号系统)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 音频几个重要的参数
- 下一篇: java信息管理系统总结_java实现科