模拟医院采血系统

模拟医院采血排队系统

(起评分85)某医院验血科室排队系统 假设某医院验血科室有两个采血窗口,其中1号窗口进行指尖采血工作,2号窗 口进行静脉采血工作。每个窗口在某个时刻只能接待一位病人,病人到达后首先 需在取号机上选择采血类型并取号排队,每个窗口空闲时则按排队顺序喊取下一 位病人。为更好利用资源提高采血效率,当某个窗口对应的待采血人数为0时系 统可以自动选择另一个窗口的病人到本窗口接收服务。请编制程序模拟医院的这 种活动,实时输出各窗口的排队情况,并在结束程序前输出所有病人的平均等待 时间。

要求:

(1)阐述算法使用的主要数据结构与实现的基本思路;

(2)给出具体编码与运行结果(包括代码和运行结果的截图);

(3)请分析算法时间复杂度和空间复杂度


阐述算法使用的主要数据结构与实现的基本思路

数据结构:

用了队列,将两种采血方式的排队用队列存储

队的结构进行了优化,增加了记录队元素数量的length。

基本思路:

利用循环,循环一百次,代表明天最多采一百个人:

循环开始:

每次输入一个数,1代表选择了一种采血方式并加入Q1队列,2代表选择了另一种采血方方式并加入Q2队列,0为无人加入队列。利用reception()函数进行叫号。

reception()里每次在两个队中各叫号一次,并实现当某个窗口对应的待采血人数为0时,系统可以自动选择另一个窗口的病人到本窗口接收服务的操作。

当输入0时无人加入队列,对剩下已经在排队的两个对进行叫号,也就是循环reception(),循环条件为(i <= Q1.length + Q2length)

循环结束


给出具体编码与运行结果(包括代码和运行结果的截图)

主函数

int main()
{
	Queue Q1,Q2;
	InitQueue(Q1);
	InitQueue(Q2);
	InHere(Q1,1);
	InHere(Q2,2);
	int n,num = 0;
	num = 10;
	int i = 1;
	while(i <= 100)
	{
		printf("请选择类型,输入数字1表示:指尖采血; 2:静脉采血; 0:表示没人加入队列\n");
		scanf("%d",&n);
		num++;
		if(n == 1){
			Push(Q1,num);
		}
		else if(n==2){
			Push(Q2,num);
		}
		else if(n==0){
			for(int j = 1;j<=Q1.length+Q2.length;j++)
			{
				reception(Q1,Q2);
			}
		}
		reception(Q1,Q2);
		i++;
	}
	return OK;
}

队列的初始化,入队,出队函数

int InitQueue(Queue &Q)//初始化
{
	Q.base = (QElemtype*)malloc(QMAXSIZE*sizeof(QElemtype));
	if(!Q.base) return ERROR;
	Q.front = Q.rear = Q.length = 0;
	return OK;
}

int Push(Queue &Q,int e)//排队(入队)
{
	if((Q.rear+1)%QMAXSIZE == Q.front) return ERROR;
	Q.base[Q.rear] = e;
	Q.length++;
	Q.rear = (Q.rear+1)%QMAXSIZE;
	return OK;
}
int Pop(Queue &Q)//出队 
{
	if(Q.rear == Q.front) return ERROR;
	printf("%d",Q.base[Q.front]);
	Q.length--;
	Q.front = (Q.front+1)%QMAXSIZE;
	return OK;
}

在这里我假定在进行操作之前,已经有十个人排好队

void InHere(Queue &Q,int n)
{
	for(int i = n;i <= 10;i = i+2)
	{
		Push(Q,i);
	}
}

排队叫号函数

void reception(Queue &Q1,Queue &Q2)//叫号函数 
{
	
		if(Q1.length > 0&&Q2.length>0){
		printf("请");Pop(Q1);printf("号到1号窗口\n");
		printf("请");Pop(Q2);printf("号到2号窗口\n");
		}
		/*.....下面的两个当当某个窗口对应的待采血人数为0时系
          统可以自动选择另一个窗口的病人到本窗口接收服务.......*/
		else if(Q1.length>0&&Q2.length<=0){
			printf("请");Pop(Q1);printf("号到1号窗口\n");
			if(Q1.length>0){
				printf("请");Pop(Q1);printf("号到2号窗口\n");
			}
		}
		else if(Q1.length<=0&&Q2.length>0){
			printf("请");Pop(Q2);printf("号到1号窗口\n");
			if(Q2.length>0){
				printf("请");Pop(Q2);printf("号到2号窗口\n");
			}
				
		} 
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#define QMAXSIZE 20
#define ERROR 0
#define OK 1
typedef int QElemtype;
typedef struct
{
	QElemtype *base;
	int front;
	int rear;
	int length;
}Queue;
int InitQueue(Queue &Q);
int Push(Queue &Q,int e);
void InHere(Queue &Q,int n);
int Pop(Queue &Q);//出队 
void reception(Queue &Q1,Queue &Q2);
int main()
{
	Queue Q1,Q2;
	InitQueue(Q1);
	InitQueue(Q2);
	InHere(Q1,1);
	InHere(Q2,2);
	int n,num = 0;
	num = 10;
	int i = 1;
	while(i <= 100)
	{
		printf("请选择类型,输入数字1表示:指尖采血; 2:静脉采血; 0:表示没人加入队列\n");
		scanf("%d",&n);
		num++;
		if(n == 1){
			Push(Q1,num);
		}
		else if(n==2){
			Push(Q2,num);
		}
		else if(n==0){
			for(int j = 1;j<=Q1.length+Q2.length;j++)
			{
				reception(Q1,Q2);
			}
		}
		reception(Q1,Q2);
		i++;
	}
	return OK;
}
int InitQueue(Queue &Q)
{
	Q.base = (QElemtype*)malloc(QMAXSIZE*sizeof(QElemtype));
	if(!Q.base) return ERROR;
	Q.front = Q.rear = Q.length = 0;
	return OK;
}

int Push(Queue &Q,int e)//排队 
{
	if((Q.rear+1)%QMAXSIZE == Q.front) return ERROR;
	Q.base[Q.rear] = e;
	Q.length++;
	Q.rear = (Q.rear+1)%QMAXSIZE;
	return OK;
}
void InHere(Queue &Q,int n)
{
	for(int i = n;i <= 10;i = i+2)
	{
		Push(Q,i);
	}
}
int Pop(Queue &Q)//出队 
{
	if(Q.rear == Q.front) return ERROR;
	printf("%d",Q.base[Q.front]);
	Q.length--;
	Q.front = (Q.front+1)%QMAXSIZE;
	return OK;
}
void reception(Queue &Q1,Queue &Q2)//叫号函数 
{
	
		if(Q1.length > 0&&Q2.length>0){
		printf("请");Pop(Q1);printf("号到1号窗口\n");
		printf("请");Pop(Q2);printf("号到2号窗口\n");
		}
		/*下面的两个当当某个窗口对应的待采血人数为0时系
		统可以自动选择另一个窗口的病人到本窗口接收服务*/
		else if(Q1.length>0&&Q2.length<=0){
			printf("请");Pop(Q1);printf("号到1号窗口\n");
			if(Q1.length>0){
				printf("请");Pop(Q1);printf("号到2号窗口\n");
			}
		}
		else if(Q1.length<=0&&Q2.length>0){
			printf("请");Pop(Q2);printf("号到1号窗口\n");
			if(Q2.length>0){
				printf("请");Pop(Q2);printf("号到2号窗口\n");
			}
				
		} 
}

 

 请分析算法时间复杂度和空间复杂度

时间复杂度:

代码中, 只要有人排队,每天会叫号叫到100个人,到100循环才会停止。

开始给队列给了20个连续的排队位置,所以在某个时间段最多每个队最多有20个人排队,共40个人。

 从第一个人到第n个人的等待时间是一个等差数列,所以每个人的平均等待时间为

n/2 * (1+n)*1/n,即(n+1)/ 2。


空间复杂度:

数据结构为顺序存储表,开始自行初始化了一个连续的存储空间,也就是当可以预测每天的采血人员时,可以自行确定存储空间,比较灵活,用这个条件下,空间利用率会比较高。

而当没有自行确定初始存储空间时,会出现当人多时,空间利用率变高,但会出现大量的人无法排队;当人少时,可以排好队,但会出现大量的空间浪费。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值