其他分享
首页 > 其他分享> > 数据结构实训 杂货店排队

数据结构实训 杂货店排队

作者:互联网

第一次写有瑕疵多多包涵
一、问题内容

该模拟程序中包含多个队列,可以使用队列数组来模拟这些队列。假设杂货店共5条收银线,顾客可随机进入支付。顾客会进入最短的队伍,如果队伍一样长,那么选择最靠近的的一个队伍。每次交易完成所消耗的时间也是随机的。
完成一些额外工作,扩展杂货店排队程序,使得客户可以:
1.如果等待超过了某个时间,可以离开队伍。
2.在给定的时间间隔内,检查另一个队伍是否更短。如果另一个队伍更短,则切换队伍。
3.如果有朋友正在排队,则可以插队。

二、详细设计
1.杂货店队列结构体
typedef struct
{ int data[MaxSize]; //保存队中元素
int front,rear; //队头和队尾指针
} People;
结构体People将用于存储顾客。
2.初始化指针
void InitQueue(People &p) //初始化循环队列p
需要输入队列,初始化输入的队列。
3.输出队列中元素的个数
int DisplayQueue(People p) //返回队列中的元素个数
需要输入队列,返回值为队列中的元素个数 。
4.顾客入队
int EnQueue(People &p) //进队
需要输入队列,将元素入队。
5.顾客出队(支付完成的出队)
int DeQueue(People &p) //出队
需要输入队列,将队列里的元素出队。
6.返回最短队
int shortline(People p,People p2,People p3,People p4,People p5)
需要输入五条队列,将每条队列调用DisplayQueue()函数的返回值放入一个数组中,返回数值最小的数组下标,如果最小值有重复返回后面最小值的数组下标。
7.顾客进入和离开
void enterandleave(People &p,People &p2,People &p3,People &p4,People &p5,int a)
需要输入五条队列和进队或出队的队列(出队=进队+5)
8.顾客排入最短队伍
void customer(People &p,People &p2,People &p3,People &p4,People &p5,int customer)
需要输入五条队列和需要进队的第几位顾客,将每条队列调用DisplayQueue()函数的返回值放入一个数组中,并与数组下标为shortline()函数的返回值的数组比较,计数最小值重复的次数并将下标放入新的数组中,如果是1次直接将shortline()函数的返回值加1,即为顾客需要进入的队列,再调用 enterandleave()函数。如果是多次,随机取一个队列,再调用 enterandleave()函数。
9.顾客出队(等不及离开的出队)
int leave(People &p)
需要输入队列,将队列里的元素出队,返回出队的元素个数。
10.顾客插队
void inserted(People &p,People &p2,People &p3,People &p4,People &p5)
需要输入五条队列,朋友和需要插队的人的队伍是随机的,如果队伍不一样则调用 enterandleave()函数。
11.顾客换队
int huan(People &p,People &p2,People &p3,People &p4,People &p5)
需要输入五条队列,使用了goto语句。调用了shortline()函数求最短队列a。用while语句循环,条件为ashortline(p,p2,p3,p4,p5)&&t。
*1.如果a>0&&a<4,调用DisplayQueue()的返回值放入一个局部变量数组total[]
*如果a俩边队列人数与a队列人数差都大于1,则随机取一条队列调用enterandleave()函数。
*Else如果total[a+1]-total[a]>1,则调用enterandleave()函数。
*Else如果total[a-1]-total[a]>1,则调用enterandleave()函数。
*Else如果total[a+2]-total[a]>1&&total[a-2]-total[a]>1&&a
2,则随机取一条队列调用enterandleave()函数。
*Else 如果total[a+2]-total[a]>1&&a!=3,则调用enterandleave()函数。
*Else如果total[a-2]-total[a]>1&&a!=1,则调用enterandleave()函数。
*Else如果total[a+3]-total[a]>1&&a1,则调用enterandleave()函数。
*Else如果total[a-3]-total[a]>1&&a
3,则调用enterandleave()函数。
*Else t=0;结束while循环。
*2.如果a0,调用DisplayQueue()的返回值放入一个局部变量数组total[]
*如果total[a+1]-total[a]>1,则调用enterandleave()函数。
*Else 如果total[a+2]-total[a]>1,则调用enterandleave()函数。
*Else 如果total[a+3]-total[a]>1,则调用enterandleave()函数。
*Else 如果total[a+4]-total[a]>1,则调用enterandleave()函数。
*Else t=0;结束while循环。
*3.如果a
4,调用DisplayQueue()的返回值放入一个局部变量数组total[]
*如果total[a-1]-total[a]>1,则调用enterandleave()函数。
*Else 如果total[a-2]-total[a]>1,则调用enterandleave()函数。
*Else 如果total[a-3]-total[a]>1,则调用enterandleave()函数。
*Else 如果total[a-4]-total[a]>1,则调用enterandleave()函数。
*Else t=0;结束while循环。
如果循环结束后t==0则结束循环,否则用goto语句前往调用shortline()函数的语句。
12.目前各个队伍状况
void cus(People p,People p2,People p3,People p4,People p5)
需要输入五条队列,将每条队列调用DisplayQueue()函数的返回值放入一个数组中,再使用for循环printf目前各个队伍状况。
13.主函数
初始化队列:调用InitQueue()函数
入队:调用EnQueue()函数
输出队列状况:调用cus()函数
输出支付完成的人数:调用cus()函数
输出支付完成的人数:需要调用DeQueue()函数
每队人数>2自动排队:需要调用customer()函数
每队人数>3且等待时间为20的倍数输出等不及离开的人数:需要调用leave()函数
每队人数>3自动排队输出插队状况:需要调用inserted()函数

三、具体代码实现如下(我用的时DEV c++的编译器)

#include<stdio.h>
#include<stdlib.h>
#include<time.h> 
#define MaxSize 100
typedef struct
{	int data[MaxSize];		//保存队中元素
	int front,rear;				//队头和队尾指针
} People;
void InitQueue(People &p)		//初始化循环队列p
{
	p.rear=p.front=0;			//指针初始化
}

int DisplayQueue(People p)		//返回队列中的元素个数 
{	
	int b=0;
   while(p.front!=p.rear)
   {
    p.front++;
    b++;	
   } 
   return b;
}
int EnQueue(People &p)	//进队
{	
	int a,i;
	a=rand()%11+20;
	for(i=0;i<a;i++)
	{
		p.data[p.rear+1]=1;
    	p.rear++;
	}
	return 1;
}

int DeQueue(People &p)		//出队
{
    int i,a;
    if(DisplayQueue(p)==0)
    	return 0;
    if(DisplayQueue(p)<=10)     //当人数过少时,出队元素最大值为总元素个数 
    	a=rand()%(DisplayQueue(p)+1);
    else
    	a=rand()%11;
	for(i=0;i<a;i++)
	{
		p.front++;
	}
	return a;
}
int shortline(People p,People p2,People p3,People p4,People p5) // 返回最短队 
{
	int total[]={DisplayQueue(p),DisplayQueue(p2),DisplayQueue(p3),DisplayQueue(p4),DisplayQueue(p5)};
	int b=total[0],c,i;
	for(i=0;i<5;i++)
	{
		if(b>=total[i])
		{
			b=total[i];
			c=i;
		}
	}	
	return c;
}
void enterandleave(People &p,People &p2,People &p3,People &p4,People &p5,int a)   
{	 
	switch(a)
	{
		case 1:	{
			p.data[p.rear+1]=1;
    		p.rear++;
			break;
		}
		case 2:{
			p2.data[p2.rear+1]=1;
    		p2.rear++;
			break;
		}
		case 3:{
			p3.data[p3.rear+1]=1;
    		p3.rear++;
			break;
		}
		case 4:{
			p4.data[p4.rear+1]=1;
    		p4.rear++;
			break;
		}
		case 5:{
			p5.data[p5.rear+1]=1;
    		p5.rear++;
			break;
		}
		case 6:	{
			p.front++;
			break;
		}
		case 7:{
			p2.front++;
			break;
		}
		case 8:{
			p3.front++;
   			break;
		}
		case 9:{
			p4.front++;
			break;
		}
		case 10:{
			p5.front++;
			break;
		}
	}
}

void customer(People &p,People &p2,People &p3,People &p4,People &p5,int customer)
{	
	int i,count=0,c[5],a;
	int total[]={DisplayQueue(p),DisplayQueue(p2),DisplayQueue(p3),DisplayQueue(p4),DisplayQueue(p5)};
	for(i=0;i<5;i++)
	{
		if(total[i]==total[shortline(p,p2,p3,p4,p5)])
		{
			c[count]=i;	
			count++;
		}
	}
	if(count!=1)
	{
		a=c[rand()%count]+1;
		enterandleave(p,p2,p3,p4,p5,a);
		printf("由于有%d条队伍一样长,第%d顾客选择最近的队伍%d队\n",count,customer+1,a);	
	}
	else 
	{	
		a=shortline(p,p2,p3,p4,p5)+1;
		enterandleave(p,p2,p3,p4,p5,shortline(p,p2,p3,p4,p5)+1);
		printf("第%d顾客成功排入最短的%d队\n",customer+1,a);
	}	
}
int  leave(People &p)
{
	int b=rand()%4;
	for(int i=0;i<b;i++)
	{
		p.front++;
	}
	return b;
}
void inserted(People &p,People &p2,People &p3,People &p4,People &p5)
{
	int friends=rand()%5+1,others=rand()%5+1;
	if(friends!=others)
	{
		enterandleave(p,p2,p3,p4,p5,friends);
		enterandleave(p,p2,p3,p4,p5,others+5);
		printf("%d队伍中有顾客在%d队伍中有朋友,并进行了插队\n",others,friends);
	}
	printf("%d队伍中有顾客在%d队伍中有朋友,并进行了插队\n",others,friends);
} 
int huan(People &p,People &p2,People &p3,People &p4,People &p5)
{	
	int a,b,t=1;
	jixv:a=shortline(p,p2,p3,p4,p5);
	if(a>0&&a<4)
	{
		while(a==shortline(p,p2,p3,p4,p5)&&t)
		{
			int total[]={DisplayQueue(p),DisplayQueue(p2),DisplayQueue(p3),DisplayQueue(p4),DisplayQueue(p5)};
			if(total[a+1]-total[a]>1&&total[a-1]-total[a]>1)
			{
				b=rand()%2;
				if(b==0)
				{
					enterandleave(p,p2,p3,p4,p5,a+1);
					enterandleave(p,p2,p3,p4,p5,a+7);	
				} 
				if(b==1)
				{
					enterandleave(p,p2,p3,p4,p5,a+1);
					enterandleave(p,p2,p3,p4,p5,a+5);	
				} 
			}
			else if(total[a+1]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+7);
			}
			else if(total[a-1]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+5);
			}
			else if(total[a+2]-total[a]>1&&total[a-2]-total[a]>1&&a==2)
			{
				b=rand()%2;
				if(b==0)
				{
					enterandleave(p,p2,p3,p4,p5,a+1);
					enterandleave(p,p2,p3,p4,p5,a+8);	
				} 
				if(b==1)
				{
					enterandleave(p,p2,p3,p4,p5,a+1);
					enterandleave(p,p2,p3,p4,p5,a+4);	
				} 
			}
			else if(total[a+2]-total[a]>1&&a!=3)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+8);
			}
			else if(total[a-2]-total[a]>1&&a!=1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+4);
			}
			else if(total[a+3]-total[a]>1&&a==1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+9);
			}
			else if(total[a-3]-total[a]>1&&a==3)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+3);
			}
			else t=0;
		}
		if(t==0)
		return 0;
		else 
		goto jixv;
	}
	else if(a==0)
	{
		while(a==shortline(p,p2,p3,p4,p5)&&t)
		{
			int total[]={DisplayQueue(p),DisplayQueue(p2),DisplayQueue(p3),DisplayQueue(p4),DisplayQueue(p5)};
			if(total[a+1]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+7);
			}
			else if(total[a+2]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+8);
			}
			else if(total[a+3]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+9);
			}
			else if(total[a+4]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+10);
			}
			else t=0;
		}
		if(t==0)
		return 0;
		else 
		goto jixv;	
	}
	else if(a==4)
	{
		while(a==shortline(p,p2,p3,p4,p5)&&t)
		{
			int total[]={DisplayQueue(p),DisplayQueue(p2),DisplayQueue(p3),DisplayQueue(p4),DisplayQueue(p5)};
			if(total[a-1]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+5);
			}
			else if(total[a-2]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+4);
			}
			else if(total[a-3]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+3);
			}
			else if(total[a-4]-total[a]>1)
			{
				enterandleave(p,p2,p3,p4,p5,a+1);
				enterandleave(p,p2,p3,p4,p5,a+2);
			}
			else t=0;
		}
		if(t==0)
		return 0;
		else 
		goto jixv;	
	}
}
void cus(People p,People p2,People p3,People p4,People p5)
{
	int total[]={DisplayQueue(p),DisplayQueue(p2),DisplayQueue(p3),DisplayQueue(p4),DisplayQueue(p5)};
	for(int num=1;num<6;num++) 
	printf("队伍%d有%d位顾客在等待\n",num,total[num-1]);
}
int main()
{
	People p,p2,p3,p4,p5;
	int a=0,b,customers,n=0,j,flag=0,f=0;
	srand((unsigned)(time(NULL)));
	InitQueue(p);
	InitQueue(p2);
	InitQueue(p3);
	InitQueue(p4);
	InitQueue(p5);
	EnQueue(p);
	EnQueue(p2);
	EnQueue(p3);
	EnQueue(p4);
	EnQueue(p5);
	cus(p,p2,p3,p4,p5);
	while(DisplayQueue(p)!=0||DisplayQueue(p2)!=0||DisplayQueue(p3)!=0||DisplayQueue(p4)!=0||DisplayQueue(p5)!=0)
	{
		getchar();
		n++;
		printf("等了%d分钟\n",5*n);
			int one=DeQueue(p);printf("第1个队伍完成交易人数为%d人\n",one);
			int two=DeQueue(p2);printf("第2个队伍完成交易人数为%d人\n",two);
			int three=DeQueue(p3);printf("第3个队伍完成交易人数为%d人\n",three);
			int four=DeQueue(p4);printf("第4个队伍完成交易人数为%d人\n",four);
			int five=DeQueue(p5);printf("第5个队伍完成交易人数为%d人\n",five);
			printf("现在队伍状况如下:\n") ;
			cus(p,p2,p3,p4,p5);
		 printf("---------------------------\n");
		 if(DisplayQueue(p)!=0||DisplayQueue(p2)!=0||DisplayQueue(p3)!=0||DisplayQueue(p4)!=0||DisplayQueue(p5)!=0)
		 {
		 	printf("排队中靠后的顾客自动排入更短的队伍\n") ;
			huan(p,p2,p3,p4,p5);
			printf("现在队伍状况如下:\n") ;
			cus(p,p2,p3,p4,p5);
			printf("---------------------------\n");
		 }
		if(DisplayQueue(p)>2&&DisplayQueue(p2)>2&&DisplayQueue(p3)>2&&DisplayQueue(p4)>2&&DisplayQueue(p5)>2)
		{
			customers=rand()%6+3;
			printf("又来%d个顾客进行排队\n",customers);
			for(int i=0;i<customers;i++)
			{
				customer(p,p2,p3,p4,p5,i);	
			}
			printf("现在队伍状况如下:\n") ;
			cus(p,p2,p3,p4,p5);
			printf("---------------------------\n");
		}	
		if(n%4==0&&DisplayQueue(p)>3&&DisplayQueue(p2)>3&&DisplayQueue(p3)>3&&DisplayQueue(p4)>3&&DisplayQueue(p5)>3)
		{    	
			b=leave(p);
			if(b=!0)
			printf("队伍1有%d位顾客离开\n",b);;
			b=leave(p2);
			if(b=!0)
			printf("队伍2有%d位顾客离开\n",b);;
			b=leave(p3);
			if(b=!0)
			printf("队伍3有%d位顾客离开\n",b);;
			b=leave(p4);
			if(b=!0)
			printf("队伍4有%d位顾客离开\n",b);;
			b=leave(p5);
			if(b=!0)
			printf("队伍5有%d位顾客离开\n",b);;
			printf("现在队伍状况如下:\n") ;
			cus(p,p2,p3,p4,p5);
			printf("---------------------------\n");
		};
		if(DisplayQueue(p)>3&&DisplayQueue(p2)>3&&DisplayQueue(p3)>3&&DisplayQueue(p4)>3&&DisplayQueue(p5)>3)
		{
			int number=rand()%5;
			for(int i=0;i<number;i++) 
			inserted(p,p2,p3,p4,p5);
			if(number!=0)
			{
				printf("现在队伍状况如下:\n") ;
				cus(p,p2,p3,p4,p5);
				printf("---------------------------\n");
			}		
		}
	}
	printf("所有交易已完成,欢迎下次光临!");
}

标签:p2,p3,total,p4,p5,People,实训,杂货店,数据结构
来源: https://blog.csdn.net/qq_52116762/article/details/122252987