cpp
复制代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MaxSize 5
static int temp; //记录队列长度
static int result; //记录编号
//人
typedef struct
{
//编号
int num;
//姓名
char name[10];
}Person;
static Person p; //记录个人(新添加的人)
//队列
typedef struct
{
//队列中的人,最多5个
Person p[MaxSize];
//队头指针
int front;
//队尾指针
int rear;
//队列长度
int length;
}SqQueue;
//顺序表
typedef struct
{
//顺序表中定义长度为2的队列数组:vip队列(0索引)和普通队列(1索引)
SqQueue Q[2];
}SqList;
//初始化队列
void InitQueue(SqQueue &Q)
{
//队头指针指向0
Q.front=0;
//队尾指针指向0
Q.rear=0;
//队列长度初始值为0,确保队列长度初始化为0
Q.length=0; //这个一定不要忘了,不然遍历时会出死循环
}
//初始化顺序表
void InitList(SqList &L)
{
for(int i=0;i<2;i++)
{
InitQueue(L.Q[i]);
}
}
/*------------------------------李新元------------------------------*/
//判断队列是否为空
bool QueueEmpty(SqQueue Q)
{
if(Q.front==Q.rear)
{
return true; //队列为空
}
else
{
return false; //队列非空
}
}
//判断队列是否已满
bool QueueCrowded(SqQueue Q)
{
if( (Q.rear+1)%MaxSize==Q.front )
{
return true; //队列已满
}
else
{
return false; //队列未满
}
}
//队列添加元素(入队列):人入队列
bool EnQueue(SqQueue &Q,Person p)
{
//判断是否队满
if(QueueCrowded(Q)) return false; //此时队满
//添加元素:此时队未满
Q.p[Q.rear]=p;
//修改尾指针
Q.rear=(Q.rear+1)%MaxSize;//利用取余运算将存储空间在逻辑上变成了"环状"
//队列长度加一
Q.length++;
//成功
return true;
}
//队列删除元素(出队列):人出队列->队头元素出队列
Person DeQueue(SqQueue &Q,Person p)
{
//判断是否队空
if(QueueEmpty(Q)) return p;
//删除元素,返回给p
p=Q.p[Q.front];
//队头指针后移
Q.front=(Q.front+1)%MaxSize;
//队列长度减一
Q.length--;
//结果(返回被删除的人)
return p;
}
/*------------------------------李新元------------------------------*/
/*------------------------------青格勒------------------------------*/
//遍历顺序表
void IndicateInfo(SqList L)
{
printf(" 编号 姓名 \n");
//先遍历的是vip队列
for(int i=0;i<L.Q[0].length;i++)
{
printf(" vip顾客:%d %s \n",L.Q[0].p[ (L.Q[0].front+i)%MaxSize ].num,
L.Q[0].p[ (L.Q[0].front+i)%MaxSize ].name);
//从头开始遍历,所以从front开始
/*printf(" vip顾客:%d %s \n",L.Q[0].p[i].num,L.Q[0].p[i].name);
在遍历队列时,最好用取余运算将存储空间在逻辑上变成了"环状",再进行遍历
也是为了正确遍历队列中的元素,避免死循环。*/
}
//再遍历的是普通队列
for(int i=0;i<L.Q[1].length;i++)
{
printf("普通顾客:%d %s \n",L.Q[1].p[ (L.Q[1].front+i)%MaxSize].num,
L.Q[1].p[ (L.Q[1].front+i)%MaxSize ].name);
//printf("普通顾客:%d %s \n",L.Q[1].p[i].num,L.Q[1].p[i].name);
}
}
//打印顺序表的第一个元素(正在办理的元素),表示办理结束,出队列,返回出队列的元素
Person IndicateOutQueue(SqList &L) //需要&,因为顺序表值变了
{
//先判断vip队列是否为空
if(QueueEmpty(L.Q[0]))
{
//vip队列为空,判断普通队列是否为空
if(QueueEmpty(L.Q[1]))
{
//普通队列为空
printf("全部办理结束 \n");
exit(0);
}
else
{
//普通队列不为空,此队列第一个元素办理结束
printf("编号为%d,姓名为%s正在办理业务 \n",L.Q[1].p[ L.Q[1].front ].num,L.Q[1].p[ L.Q[1].front ].name);
printf("办理结束 \n");
//第一个元素出队列并返回出队列的元素
return DeQueue(L.Q[1],L.Q[1].p[ L.Q[1].front ]);
}
}
else
{
//vip队列不为空,此队列第一个元素办理结束
printf("编号为%d,姓名为%s正在办理业务 \n",L.Q[0].p[ L.Q[0].front ].num, //不是L.Q[0].p[0].num
L.Q[0].p[ L.Q[0].front ].name);
printf("办理结束 \n");
//第一个元素出队列并返回出队列的元素
return DeQueue(L.Q[0],L.Q[0].p[ L.Q[0].front ]);
}
}
/*------------------------------青格勒------------------------------*/
/*------------------------------杨志------------------------------*/
//判断所在队列是否满员,然后决定是否添加元素,如果添加了,返回添加的元素
Person IncreasePerson(SqList &L,int result) //要加&,因为顺序表值变了
{
if(result!=1&&result!=2)
{
printf("前先说明是否为vip \n");
goto loop;//直接跳到loop里的return语句,此时p就为NULL,是空值,这里不能直接return NULL
}
if(QueueCrowded( L.Q[result-1]) )
{
//队列已满.无法添加
printf("所在队列已满,请在线上操作");
exit(0);
}
else
{
//所在队列未满
printf("所在队列未满 \n");
//创建新的元素
Person p;
//领取编号
temp=L.Q[result-1].length;
p.num=++temp; //是++temp,因为是先把长度自增后才是下一个元素的编号的值,再赋值,b不是temp++,temp++是先赋值再自增
printf("编号为%d \n",p.num);
//填写姓名
printf("请输入姓名:");
scanf("%s",p.name);
//添加
EnQueue(L.Q[result-1],p);
//返回添加的元素
loop:return p;
}
}
/*------------------------------杨志------------------------------*/
/*------------------------------刘佳鑫------------------------------*/
//比较姓名和编号来判断是否轮到自己(result就1和2两个值)
bool strcmpInfo(SqList L,int result,Person p)
{
//比姓名
int flag=strcmp(L.Q[result-1].p[ L.Q[result-1].front ].name,p.name);
//比姓名和编号
if(flag==0&&L.Q[result-1].p[ L.Q[result-1].front ].num==p.num)
{
printf("轮到自己办理 \n");
printf("办理结束 \n");
return true;
}
else
{
printf("前面还有顾客,请耐心等待 \n");
return false;
}
}
/*------------------------------刘佳鑫------------------------------*/
/*------------------------------王豪杰------------------------------*/
//判断是否到自己的函数(result就1和2两个值)
bool OwnInfo(SqList L,int result,Person p)
{
if(result!=1&&result!=2)
{
printf("前先说明是否为vip \n");
return false;
}
//为了提高效率,先判断自己是否是vip,然后在对应的队列查找
if(result==1)
{
//属于vip队列,判断此时vip队列里的第一个元素是否和自己匹配
bool flag=strcmpInfo(L,result,p);
//判断
if(flag) return true;
else return false;
}
else if(result==2)
{
//属于普通队列,需要先看vip队列是否办理完,vip办理完才能到普通队列
if(QueueEmpty(L.Q[0]))
{
//此时vip客户已经办完
bool flag=strcmpInfo(L,result,p);
//判断
if(flag) return true;
else return false;
}
else
{
printf("请先等待vip客户办理完 \n");
return false;
}
}
}
/*------------------------------王豪杰------------------------------*/
int main()
{
//1.创建两个队列,再存入顺序表
SqQueue vipQ; //vip队列
SqQueue comQ; //普通队列
//2.创建顺序表
SqList L;
L.Q[0]=vipQ;
L.Q[1]=comQ;
//3.初始化顺序表
InitList(L);
//4.vip队列和普通队列各定义一个元素
Person p1={1,"张三"}; //vip队列
Person p2={1,"李四"}; //普通队列
Person p3={2,"赵六"}; //普通队列
//5.往vip队列和普通队列各自存入元素
EnQueue(L.Q[0],p1);
EnQueue(L.Q[1],p2);
EnQueue(L.Q[1],p3);
//6.输出顾客信息
printf("正在排队的客户如下(vip队列和普通队列各队列最多5人): \n");
IndicateInfo(L);
printf("------------------------------------------------------------- \n");
//7.操作界面
printf(" 欢迎来到银行办理业务中心 \n");
printf(" 1.输入是否为vip 2.取号 \n");
printf(" 3.查看当前正在办理的客户 4.查看是否轮到自己 \n");
printf(" 5.查看正在排队的客户 6.停止办理 \n");
//8.开始操作
while(true)
{
int choose;
printf("请输入接下来的操作:");
scanf("%d",&choose);
switch(choose)
{
case 1:
{
//输入自己是否是vip
printf("是否是vip:1.是 2.不是(输入编号即可) \n");
scanf("%d",&result);
printf("------------------------------------------------------------- \n");
break;
}
case 2:
{
//判断所在队列是否满员,然后决定是否添加元素(取号)
p=IncreasePerson(L,result); //p这个变量属于自己的信息,全局要用,最好设为全局变量
printf("------------------------------------------------------------- \n");
break;
}
case 3:
{
//查看当前正在办理的客户,然后办理完的客户出队列
Person ownP=IndicateOutQueue(L); //ownP这个变量只在这个case语句中判断一下即可,没必要设为全局变量
//判断自己是否已经办理完
//比姓名
int flag=strcmp(ownP.name,p.name);
//比姓名和编号
if(flag==0&&ownP.num==p.num)
{
printf("您已经办理完 \n");
exit(0);
}
else
{
printf("还没轮到您,请稍等 \n");
}
printf("------------------------------------------------------------- \n");
break;
}
case 4:
{
//判断是否到了自己
if( OwnInfo(L,result,p) ) exit(0); //此时到了自己,办理结束,退出
printf("------------------------------------------------------------- \n");
break;
}
case 5:
{
//查看正在排队的客户
IndicateInfo(L);
printf("------------------------------------------------------------- \n");
break;
}
case 6:
{
//删除自己的位置
DeQueue(L.Q[result-1],p);
//退出
exit(0);
}
default:
{
printf("不存在该选项 \n");
printf("------------------------------------------------------------- \n");
break;
}
}
}
return 0;
}