编写病人看病模拟程序

编写病人看病模拟程序

目的:掌握队列应用的算法设计

内容:编写一个程序,反应病人到医院排队看医生的情况。在病人排队过程中主要重复下面两件事。
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	//输入输出头文件
#include	//标准头文件
#include	//字符串头文件
#include	//布尔类型头文件

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;
}

你可能感兴趣的:(队列,指针)