一、实验目的
队列的应用,结合应用实例,深入理解和掌握队列。
二、实验软硬件要求
1、VC++ 6.0
三、实验预习
队列基本操作
四、实验内容(实验步骤、测试数据等)
1、队列基本操作。请选择循环队列结构或链式队列结构实现队列的基本操作(包括初始化、入队、出队等),并在主函数中进行入队出队等操作,检验算法正确性。(必做)
2、编写一个程序,反映病人到医院看病,排队看医生的情况。在病人排队过程中,主要重复两件事:(选做)
(1)病人到达诊室,将病历交给护士,排到等待队列中候诊。
护士从等待队列中取出下一位病人的病历,该病人进入诊室就诊。
要求模拟病人等待就诊这一过程。程序采用菜单方式,其选项及功能说明如下:
排队——输入排队病人的病历号,加入到病人排队队列中。
就诊——病人排队队列中最前面的病人就诊,并将其从队列中删除。
查看排队——从队首到队尾列出所有的排队病人的病历号。
不再排队,余下顺序就诊——从队首到队尾列出所有的排队病人的病历号,并退出运行。
(5)下班——退出运行,提示未就诊的病人明天再来。
运行结果:
实验体会
(可以记录C语言中薄弱的部分,便于课后复习巩固,每次实验体会需要写两行。)
第二个实验的难度较大,本章对于队列的逻辑理解较好,但是C语言基础薄弱,即使知道原理也无法独立写出代码。注意点:队列特点为先进先出,front==rear时表示队列满或空,另设tag,当tag==1时表示满,tag==0时表示空,队列满则返回0
六、源代码或重要代码
实验一
#include <stdio.h>
#include <stdlib.h>
typedef int Elemtype;
//声明一个结构体来表示节点
typedef struct Node
{
Elemtype data; //节点数据域
struct Node * next; //节点指针域
}QueueNode;
//声明一个结构体来定义上面这个结构体的两个指针
typedef struct
{
QueueNode *front,*rear;//分别指向队首和队尾的指针
}LinkQueue;
//首先进行初始化
void Init(LinkQueue *s)
{
QueueNode * p;
p=(QueueNode*)malloc(sizeof(QueueNode));
p->next=NULL;
s->front=s->rear=p;
}
//判断队列是否为空,为空返回真1,不为空返回假0
int Empty(LinkQueue s)
{
//队空的条件是头指针和尾指针指向相同的地方
if(s.front==s.rear)
{
return 1;
}
return 0;
}
//求队列长度
int GetLength(LinkQueue s)
{
//声明一个节点类型的指针
QueueNode *p;
//让p指向队列的头指针
p=s.front;
//声明一个变量用来记录队列当前长度
int length=0;
while(p->next)//当指针p所指的节点不为空时执行循环体
{
length++;
p=p->next;
}
return length;//返回当前队列的长度
}
//入队操作
void Add(LinkQueue *s,Elemtype x)
{
//声明一个节点类型的指针变量用来存储要入队的元素
QueueNode *p;
p=(QueueNode*)malloc(sizeof(QueueNode));
if(!p){
printf("内存分配失败\n\n");
return;
}
p->data=x; //指针指向的节点的数据域存放x
p->next=NULL; //指针指向的节点的指针域置为空
s->rear->next=p; //将队列的尾指针的指针域next指向指针p所指的节点
s->rear=p; //将队列的尾指针向后移一位,指向刚入队的节点的位置
}
//获取队首元素
Elemtype GetTop(LinkQueue s)
{
//首先判断队列是否为空
if(Empty(s))
{
printf("队列为空,无法获取队首元素\n\n");
return 0;
}
return s.front->next->data;//不为空的话就返回队首指针指向的第一个元素的数据域
}
//出队操作
void Del(LinkQueue *s,Elemtype *e)
{
//先判断队列是否为空
if(Empty(*s))
{
printf("当前队列为空,无法执行出队操作\n\n");
return;
}
//用临时变量保存出队的元素
QueueNode *p;
p=s->front->next;
if(p==s->rear)
{
s->front=s->rear;
}
*e=p->data;
s->front->next=p->next;
free(p);
}
int main()
{
//声明一个节点类型的变量
Elemtype e;
//声明一个顺序队名字为s
LinkQueue s;
//对这个顺序队进行初始化
Init(&s);
printf("==============================================================\n");
printf("当前队列是否为空,为空返回真1,不为空返回假0:%d\n\n",Empty(s));
printf("当前队列的长度为:%d\n\n",GetLength(s));
//执行入队操作
Add(&s,5);
Add(&s,4);
Add(&s,6);
Add(&s,2);
printf("==============================================================\n");
printf("当前队列是否为空,为空返回真1,不为空返回假0:%d\n\n",Empty(s));
printf("当前队列的长度为:%d\n\n",GetLength(s));
//获取当前队首元素
printf("==============================================================\n");
e=GetTop(s);
if(e){
printf("当前队列的队首元素为:%d\n\n",e);
}
//执行出队操作
printf("==============================================================\n");
Del(&s,&e);
printf("出队的元素为:%d,当前队列的长度为:%d\n\n",e,GetLength(s));
//获取当前队首元素
e=GetTop(s);
if(e){
printf("当前队列的队首元素为:%d\n\n",e);
}
//再执行一次出队操作
printf("==============================================================\n");
Del(&s,&e);
printf("出队的元素为:%d,当前队列的长度为:%d\n\n",e,GetLength(s));
//获取当前队首元素
e=GetTop(s);
if(e){
printf("当前队列的队首元素为:%d\n\n",e);
}
//再执行一次出队操作
printf("==============================================================\n");
Del(&s,&e);
printf("出队的元素为:%d,当前队列的长度为:%d\n\n",e,GetLength(s));
//获取当前队首元素
e=GetTop(s);
if(e){
printf("当前队列的队首元素为:%d\n\n",e);
}
return 0;
}
实验二
#include <stdio.h>
#include <malloc.h>
//链队结点类型
typedef struct qnode
{
int data;
struct qnode *next;
} QNode; /*链队结点类型*/
//链队类型
typedef struct
{
QNode *front,*rear;
} QuType; /*链队类型*/
//模仿看病流程函数
void SeeDoctor()
{
int sel,flag=1,find,no;
QuType *qu;
QNode *p,*q;
qu=(QuType *)malloc(sizeof(QuType)); /*创建空队*/
qu->front=qu->rear=NULL;
while (flag==1) /*循环执行*/
{
printf("1:排队 2:就诊 3:查看排队 4.不再排队,余下依次就诊 5:下班 请选择:");
scanf("%d",&sel);
switch(sel)
{
case 1:
printf(" >>输入病历号:");
do
{
scanf("%d",&no);
find=0;
p=qu->front;
while (p!=NULL && !find)
{
if (p->data==no)
find=1;
else
p=p->next;
}
if (find)
printf(" >>输入的病历号重复,重新输入:");
}
while (find==1);
p=(QNode *)malloc(sizeof(QNode)); /*创建结点*/
p->data=no;
p->next=NULL;
if (qu->rear==NULL) /*第一个病人排队*/
{
qu->front=qu->rear=p;
}
else
{
qu->rear->next=p;
qu->rear=p; /*将*p结点入队*/
}
break;
case 2:
if (qu->front==NULL) /*队空*/
printf(" >>没有排队的病人!\n");
else /*队不空*/
{
p=qu->front;
printf(" >>病人%d就诊\n",p->data);
if (qu->rear==p) /*只有一个病人排队的情况*/
{
qu->front=qu->rear=NULL;
}
else
qu->front=p->next;
free(p);
}
break;
case 3:
if (qu->front==NULL) /*队空*/
printf(" >>没有排列的病人!\n");
else /*队不空*/
{
p=qu->front;
printf(" >>排队病人:");
while (p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
break;
case 4:
if (qu->front==NULL) /*队空*/
printf(" >>没有排列的病人!\n");
else /*队不空*/
{
p=qu->front;
printf(" >>病人按以下顺序就诊:");
while (p!=NULL)
{
printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
flag=0; /*退出*/
break;
case 5:
if (qu->front!=NULL) /*队不空*/
printf(" >>请排队的病人明天就医!\n");
flag=0; /*退出*/
break;
}
}
p=qu->front; //销毁队列
while (p!=NULL)
{
q = p->next;
free(p);
p = q;
}
}
//主函数
int main()
{
SeeDoctor();//调用病人看病函数
return 0;
}