编写病人看病模拟程序
目的:掌握队列应用的算法设计
内容:编写一个程序,反应病人到医院排队看医生的情况。在病人排队过程中主要重复下面两件事。
1:病人到达诊室,将病历本交给护士,排到等待队列中候诊。
2:护士从等待队列中取出下一位病人的病例,该病人进入诊室候诊。
要求模拟病人等待就诊这一过程。程序采用菜单方式,其选项及功能说明如下:
1):排队——输入排队病人的病历号,加入到病人排队队列中;
2):就诊——病人排队队列中最前面的病人就诊,并将其从队列中删除;
3):查看排队——从队首到队尾列出所有的排队病人的病历号;
4):不再排队,余下依次就诊——从队首到队尾列出所有的排队病人的病历号,并退出运行。
5):下班——退出运行。
思路:因为没有限制排队人数,故采用链队结构,然后利用队列的基本操作实现程序的功能。
定义结构体:
typedef long long int Elemtype; //该队列中的元素超长整型
typedef struct Quene* List; //将该队列结点的指针命名为List
typedef struct LinkQuene* SqList; //将该队列类型的指针命名为SqList
struct Quene //定义结点
{
Elemtype data; //存放病历号
List next; //下一个结点指针
};
struct LinkQuene
{
List front; //指向队首结点
List rear; //指向队尾结点
};
算法实现
bool Test(SqList q)
{
int n;
List p;
bool flag = false; //是否关闭程序,默认为“否”
Elemtype e;
InitQuene(q); //创建链队
menu(); //输出菜单
while (scanf_s("%d", &n) != EOF) {
switch (n) {
case 1:printf("请输入您的病历号(不超过十位的整数):");
scanf_s("%lld", &e);
while (e > 1e10) {
printf("\n病历号不合规,重新输入:");
scanf_s("%lld", &e);
}
enQuene(q, e); //将病历号入队
printf("\n排队成功。\n");
break;
case 2:if (!QueneEmpty(q)) {
deQuene(q, e); //当有人排队,即队不为空时出队
printf("就诊成功。\n");
}
else
printf("当前无人排队。\n");
break;
case 3:p = q->front; //遍历一遍链队
printf("排在您前面的人有:\n");
while (p != NULL) {
printf("%lld\n", p->data);
p = p->next;
}
break;
case 4:p = q->front; //遍历一遍链队
printf("排在您前面的人有:\n");
while (p != NULL) {
printf("%lld\n", p->data);
p = p->next;
}
flag = true;
break;
case 5:flag = true;
break;
default:printf("指令错误,重新输入。\n");
}
if (flag)
break;
menu();
}
DestroyQuene(q); //销毁链队
return true;
}
与主函数相结合
#include<stdio.h> //输入输出头文件
#include<stdlib.h> //标准头文件
#include<string.h> //字符串头文件
#include<stdbool.h> //布尔类型头文件
typedef long long int Elemtype; //该队列中的元素超长整型
typedef struct Quene* List; //将该队列结点的指针命名为List
typedef struct LinkQuene* SqList; //将该队列类型的指针命名为SqList
struct Quene //定义结点
{
Elemtype data; //存放病历号
List next; //下一个结点指针
};
struct LinkQuene
{
List front; //指向队首结点
List rear; //指向队尾结点
};
bool InitQuene(SqList& q); //初始化队列
bool DestroyQuene(SqList& q); //销毁队列
bool QueneEmpty(SqList& q); //判断队列是否为空
bool enQuene(SqList& q, Elemtype& e); //进队列
bool deQuene(SqList& q, Elemtype& e); //出队列
bool Test(SqList q); //病人看病模拟程序
void menu(void); //菜单
int main(int argc, const char* argv[])
{
SqList q = NULL;
bool flag = Test(q);
if (flag)
printf("谢谢使用,再见。\n");
return 0;
}
bool Test(SqList q)
{
int n;
List p;
bool flag = false; //是否关闭程序,默认为“否”
Elemtype e;
InitQuene(q); //创建链队
menu(); //输出菜单
while (scanf_s("%d", &n) != EOF) {
switch (n) {
case 1:printf("请输入您的病历号(不超过十位的整数):");
scanf_s("%lld", &e);
while (e > 1e10) {
printf("\n病历号不合规,重新输入:");
scanf_s("%lld", &e);
}
enQuene(q, e); //将病历号入队
printf("\n排队成功。\n");
break;
case 2:if (!QueneEmpty(q)) {
deQuene(q, e); //当有人排队,即队不为空时出队
printf("就诊成功。\n");
}
else
printf("当前无人排队。\n");
break;
case 3:p = q->front; //遍历一遍链队
printf("排在您前面的人有:\n");
while (p != NULL) {
printf("%lld\n", p->data);
p = p->next;
}
break;
case 4:p = q->front; //遍历一遍链队
printf("排在您前面的人有:\n");
while (p != NULL) {
printf("%lld\n", p->data);
p = p->next;
}
flag = true;
break;
case 5:flag = true;
break;
default:printf("指令错误,重新输入。\n");
}
if (flag)
break;
menu();
}
DestroyQuene(q); //销毁链队
return true;
}
void menu(void)
{
printf("==========================\n");
printf("=======选择您的操作=======\n");
printf("== 1.排队 ==\n");
printf("== 2.就诊 ==\n");
printf("== 3.查看排队 ==\n");
printf("== 4.不再排队 ==\n");
printf("== 5.下班 ==\n");
printf("==========================\n");
}
bool InitQuene(SqList& q)
{
q = (SqList)malloc(sizeof(LinkQuene));
//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
while (!q) {
q = (SqList)malloc(sizeof(Quene));
}
q->front = q->rear = NULL; //此时队列无元素(两个下标之间差的绝对值为0)
return true;
}
bool DestroyQuene(SqList& q)
{
List p; //工作指针
while (q->front != q->rear) { //当队列中的结点大于一个时循环
p = q->front; //工作指针指向队首结点
q->front = q->front->next; //队首结点后移
free(p); //释放掉工作指针指向的结点
}
p = q->front;
free(p); //释放掉最后一个结点
free(q); //释放掉链队结点
return true;
}
bool QueneEmpty(SqList& q)
{
return (q->front == NULL); //当队列为空时返回“真”,否则返回“假”
}
bool enQuene(SqList& q, Elemtype& e)
{
List p = (List)malloc(sizeof(Quene));
//malloc有一定几率申请空间失败,此时继续申请,直到申请成功
while (!p) {
p = (List)malloc(sizeof(Quene));
}
p->data = e;
p->next = NULL;
if (q->rear == NULL)
q->front = q->rear = p; //当链队为空时,新结点既是头结点又是尾结点
else {
q->rear->next = p; //将新结点接到队尾
q->rear = p; //队尾移动
}
return true;
}
bool deQuene(SqList& q, Elemtype& e)
{
if (q->front == NULL) //当队列为空时无法出队,返回“假”
return false;
List p = q->front; //工作指针指向队首
if (q->front == q->rear) //当链队中只有一个结点时
q->front = q->rear = NULL;
else //当链队中有一个以上的结点时
q->front = q->front->next;
e = p->data;
free(p);
return true;
}