数据结构实训 杂货店排队
作者:互联网
第一次写有瑕疵多多包涵
一、问题内容
该模拟程序中包含多个队列,可以使用队列数组来模拟这些队列。假设杂货店共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&&a2,则随机取一条队列调用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&&a3,则调用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.如果a4,调用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