今天是用队列的基本操作来解决舞伴问题的实验
实验目的:1.掌握队列的定义及实现;
2.掌握利用队列的基本操作。
实验要求:1.使用链式结构完成队列的各种基本操作;
2.补充完善舞伴问题。
队列和栈相反,它是一种先进先出的线性表。只允许在表的一端进行插入,而在另一端进行删除。与栈不同,栈的插入和删除只在栈顶一端进行。队列的存储结构如下:
typedef struct QNode
{
QElemtype data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct
{
QueuePtr front;//队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
初始化:构造一个只有一个头结点的空队。
【算法描述】
Status InitQueue(LinkQueue &Q)
{
Q.front=Q.rear=new QNode;
Q.front->next=NULL;
return OK;
}
入队:链队在实行入队的基本操作时,并不像循环队列需要判断对是否满,只需要为入队元素动态分配一个结点空间。
【算法描述】
Status EnQueue(LinkQueue &Q,QElemType e)
{
p=new QNode;
p->data=e; //数据域置为e
p->next=NULL;Q.rear->next=p; //将新结点插入到队尾
Q.rear=p; //修改队尾指针
return OK;
}
出队:链队出队需要判空,不仅如此,出完队之后,还要释放队头元素的所占空间。
【算法描述】
Status DeQueue(LinkQueue &Q,QElemType &e)
{
if(Q.front==Q.rear) return ERROR; //队为空的情况
P=Q.front->next; //指向队头元素
e=p->data; //保存队头元素的值
Q.front->next=p->next; //修改头结点的指针域
if(Q.rear==p) Q.rear=Q.front; //最后一个元素被删,队尾指针指向头结点
delete p; //释放原队头元素空间
return OK;
}
取队头元素:需要判空,当不为空时,返回当前队头元素的值,队头指针保持不变。
【算法描述】
SElemType GetHead(LinkQueue Q)
{
if(Q.front!=Q.rear);
return Q.front->next->data;
}
其实队列同样也有顺序结构的,但出于本实验的要求,这里只用了链队的相关内容,下面的程序代码就是关于这次实验的全部代码,在这之前,我还是要给出一下判断整个队列为空的代码,因为实际情况中,队列为空的情况也是存在的,并不是理想化,所以我觉得有那个必要。
【算法描述】
Status QueueEmpty(LinkQueue &Q) //判断队列是否为空
{
if(Q.front==Q.rear)
return OK;
else
return ERROR;
}
以下就是完整代码
【完整代码】
#include<stdio.h>
#define OK 1
#define ERROR 0
typedef int Status;
typedef struct
{
char name[20];
char sex; //F表示女性,M表示男性
}Person;
typedef Person QElemType;
typedef struct QNode //链式储存结构
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
//舞伴队列
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear; //队尾指针
}LinkQueue;
Status InitQueue(LinkQueue &Q) //构建空队列
{
Q.front=Q.rear=new QNode; //生成新结点
Q.front->next=NULL;
return OK;
}
//入队
Status EnQueue(LinkQueue &Q,QElemType e)
{
QueuePtr p;
p=new QNode; //为入队元素分配节点空间
p->data=e; //将新结点数据域置为e
p->next=NULL;
Q.rear->next=p; //新结点插入到尾队
Q.rear=p;
return OK;
}
//出队
Status DeQueue(LinkQueue &Q,QElemType &e)
{
QueuePtr p;
if(Q.front==Q.rear)
return ERROR;
p=Q.front->next; //p指向队头元素
e=p->data; //e保存队头元素的值
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front; //存在唯一的一个元素时
delete p; //释放原队头元素的空间
return OK;
}
//取队头元素
QElemType GetHead(LinkQueue Q) //返回Q的队头元素,不修改对头指针
{
if(Q.front!=Q.rear)
return Q.front->next->data; //队头指针不变
}
Status QueueEmpty(LinkQueue &Q) //判断队列是否为空
{
if(Q.front==Q.rear)
return OK;
else
return ERROR;
}
void DancePartner(Person dancer[],int num)
{//结构数组dancer中存放跳舞的男女,num是跳舞的人数
LinkQueue Mdancers,Fdancers;//队列初始化
int i;
Person p;
InitQueue(Mdancers);
InitQueue(Fdancers);
for(i=0;i<num;i++) //将舞者依次根据性别入队
{
p=dancer[i];
if(p.sex=='F')
EnQueue(Fdancers,p); //插入女队
else
EnQueue(Mdancers,p); //插入男队
}
printf("The dancing partners are: \n");
while(!QueueEmpty(Fdancers)&&!QueueEmpty(Mdancers)) //依次输出男女舞伴的姓名
{
DeQueue(Fdancers,p);
printf("%s--",p.name); //输出出队女士名字
DeQueue(Mdancers,p);
printf("%s\n",p.name); //输出出队男士名字
}
if(!QueueEmpty(Fdancers))
{
p=GetHead(Fdancers); //取女士对头
printf(" The first woman to get a partner is: %s\n",p.name);
}
else if(!QueueEmpty(Mdancers))
{
p=GetHead(Mdancers); //取男士队头
printf(" The first man to get a partner is: %s\n",p.name);
}
}
int main()
{
int i,n;
Person dancer[20];
printf("请输入舞池中排队的人数:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("姓名:");
scanf("%s",dancer[i].name);
getchar();
printf("性别:");
scanf("%c",&dancer[i].sex);
}
DancePartner(dancer,n);
}
要是有什么不理解的地方,或者需要给小生指正的地方,欢迎再下方留言!
【参考文献】:《数据结构》(C语言版|第2版)严蔚敏 李冬梅 吴伟民编著