队列舞伴问题

今天是用队列的基本操作来解决舞伴问题的实验
实验目的: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版)严蔚敏 李冬梅 吴伟民编著

发布了35 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43873385/article/details/104011015