主頁 > 軟體設計 > 資料結構——佇列(銀行叫號系統)

資料結構——佇列(銀行叫號系統)

2020-12-20 12:18:38 軟體設計

資料結構——佇列(銀行叫號系統)

一、實驗目的

(1)掌握佇列的鏈式存盤結構

(2)掌握佇列的基本操作,并能進行應用實踐

(3)使用C/C++語言和佇列實作”銀行叫號系統“專題

二、實驗任務

設計一個控制臺程式,模擬銀行排隊業務,要求實作功能:

(1)輸出程式界面,提示客戶輸入銀行視窗數量和開放視窗時間

(2)客戶隨機時間進入銀行,程式在事件表中記錄客戶進入時間和離開時間,并將客戶排入視窗佇列,辦理完業務后退出佇列
(3)視窗開放時間結束,客戶停止進入銀行,直到所有客戶退出佇列之后計算出客戶的平均服務時間

三、實驗代碼

1.事件串列
1)定義事件結點

typedef struct Event//定義事件結點
{
	int occurTime;//發生時刻
	int type;//事件型別:0表示顧客到達;1~N表示顧客從N號視窗離開
	struct Event *next;
}Event,*EventList;

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;
	else
		return 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);
		else
			printf("第%d分鐘,%d號視窗的客戶即將離開,\n",pTmp->occurTime,pTmp->type);
	}
	printf("\n");
	return OK;
}

2.鏈式佇列
1)定義鏈式佇列資料結構

typedef struct QElemType{//定義鏈式佇列資料結構
	int arriveTime;//到達時間
	int duration;//持續時間
	struct QElemType *next;
}QElemType;
typedef struct LinkedQueue{
	QElemType *front;//頭指標
	QElemType *rear;//尾指標
}LinkedQueue;

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 
	{//指向首結點后一個元素,并復制給pQElem
		pTmp=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)定義全域變數

#define MAXSIZE 20//銀行服務視窗最大數量
int gWindowsNum;//銀行服務視窗數
int gCustomerNum;//客戶總人數
int gTotalTime;//總服務時間
int gCloseTime;//銀行關閉時間
EventList gEventList;//事件串列
Event gEvent;//事件
LinkedQueue gQueue[MAXSIZE];//佇列陣列
QElemType gCustomer;//佇列結點

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;//佇列編號為視窗編號-1
	DelQueue(&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( );
		else
			CustomerLeaved( );
		//顯示當前事件串列,以及排隊情況
		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@)!,蟹蟹啦!*

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/237689.html

標籤:其他

上一篇:類與物件(一)4. 書籍類的設計與實作

下一篇:C語言編程>第五周 ⑦ 求1-1000中能被7或能被11,但不能同時被7和11整除的數。每10個為一行顯示。

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more