数据结构实验--学生搭配问题

一、   题目描述

     一班有m个女生,有n个男生(m不等于n),现要开一个舞会. 男女生分别编号坐在舞池的两边的椅子上.每曲开始时,依次从男生和女生中各出一人配对跳舞, 本曲没成功配对者坐着等待下一曲找舞伴.

请设计一系统模拟动态地显示出上述过程,要求如下:

1) 输出每曲配对情况

2) 计算出任何一个男生(编号为X)和任意女生(编号为Y),在第K曲配对跳舞的情况.至少求出K的两个值.

3) 尽量设计出多种算法及程序,可视情况适当加分

二、需求分析

本实验要对数目不等的男生女生跳舞进行搭配,设计需要解决每一首曲子                                                                                                                          

     男生女生的搭配情况,要采用循环队列的模式来解决,男生和女生各在两个循环

     的队列中,每首曲子开始,便在两个队首各取一人成功配对跳舞,并进入队尾,  

 等待下一次配对。

       例如:(3男5女情况)          

                                第一首:男1和女1

                      第二首:男2和女2

                                                 ………

                  第四首:男1和女4

三、概要设计

为实现上述功能和目的,要用到循环队列的相关知识,同时,要定义一定的抽的数据类型,主函数调用各个函数模块。

1.各模块函数介绍:

1)class cirularQueue

作用:定义一个一个循环队列

2)~cirularQueue() 

作用:定义析构函数,使对象在撤销时释放

3)bool IsFull()      

作用:判断队列是否已满

4)bool IsEmpty()    

作用:判断队列是否为空,用于出队列前使用

5)void push(T info) 

作用:入队。每对舞伴跳完舞之后,做入队处理,到达队尾,等待下次跳舞。

6)void Pop(T &info)  

作用:出队。每取曲子响起时男生队列和女生队列作出队处理,两人跳舞。

7)void GetHead(T &info)

作用:取队首元素,对出队的男女进行识别。

8)void Initqueue(cirularQueue<int>&,int);

作用:初始化队列

9)void display(int,int);

作用:根据男生和女生的人数和曲目的数目,来判断每曲歌的男女配对情况

    10)void charge(int,int);

    作用:判断指定组合能否配对成功

 

2.本程序包含三个模块:

 

1)主程序模块:

       void main()

{

          初始化;

        do{

               接受命令;

                处理命令;

}while(“命令”=”退出”)

 

 }

2)、集合单元模块——实现集合的各个函数模块

3)、结点结构单元模块——定义集合的结点结构

五、调试分析

  本实验采用的是循环队列的基本操作顺利的解决学生舞曲搭配问题,主要利用用循环队列的环状结构,循环地执行出列入列操作并在出队列时进行配对并输出配对情况,而整个过程不需要不需要移动元素使程序在空间复杂度上降到最小,采用指针的移动大大加快了程序的执行效率。并且对输入进行了改进,以防止用户随意输入时出现的各种意想不到的错误。

六、总结

本次程序设计中所用语言为C++,程序开始定义了类cirular,其中有头指针,尾指针及数据域等。随之定义了析构函数,释放对象,然后进行了队列的基本操作,有队列的申明,判断队空及队满,出队,入队,其核心是display()函数和charge()函数,其中display()用于对各位同学编号和每队的输出情况,charge()用于计算已编号的同学在第几曲中进行配对。循环队列是一种环状的队列并且对头元素指向队尾元素,学生搭配问题是典型的只有采用循环队列才能解决的问题,实验表明该算法的空间复杂度优于其他算法。

通过这次实验,我发现自己在数据结构这方面真是知之甚少,以前学习的知识也多有

忘。与其说这是一次学习,倒不如说这是一次检测。所以,这次实验让我很好的认清自己对数据结构这门课学习程度如何,知道自己哪些方面还存在不足、对该学科重视程度还不够,以后要努力学习。对一学期的学习的数据结构通过这次实验,虽然并没有掌握的非常好,但是对某些重点需要掌握和了解的还是有了深入的探讨,也让我明白学的东西再多也要学会运用,通过实例去探讨可能比理论上更容易理解。

七、附录

源程序名清单

#include<iostream>
using namespace std;
template <class T>
class cirularQueue  //定义一个一个循环队列
{ private:
  int MaxSize;
  int first;    //头指针
  int last;     //尾指针
  T *data;
  public:
  cirularQueue(int MaxLength)
  {  MaxSize=MaxLength;
     first=last=0;
    data=new T[MaxLength];
  }
~cirularQueue()  //定义析构函数,使对象在撤销时释放
{  first=last=0;
   delete []data;
 }
void Initqueue()    //队列的声明
{  for(int i=0;i<MaxSize-1;i++)
   push(i);
}
bool IsFull()       //判断队列是否已满
{  if((last+1)%MaxSize==first)
      return  true;
   else return false;
}
bool IsEmpty()     //判断队列是否为空
{  if(first==last)
     return true;
   else return false;
}
void push(T info)  //入队
{      if(IsFull())
   {   cout<<"错误!队列已满!"<<endl;
}
   else
   {  data[last]=info;
      last=(last+1)%MaxSize;
    }
}
void Pop(T &info)   //出队
{    if(IsEmpty())
   {  cout<<"错误!队列为空!"<<endl;
       }
   else
   {  info=data[first];
    first=(first+1)%MaxSize;
    }
}
void GetHead(T &info)  //取队首元素
 {     if(IsEmpty())
   {   cout<<"错误!队列为空!"<<endl;

}
   else
   {   info=data[first];
    }
 }
};
void Initqueue(cirularQueue<int>&,int);
void display(int,int);
void charge(int,int);
using namespace std;
static int songnum=0;  //定义歌曲的数量并初始化为0
static int m=0,n=0;    //男生和女生的人数
int main()             //主函数
{   cout<<"请分别输入男生和女生的人数:";
    cin>>m>>n;
    display(m,n);
    int a=0,b=0;     //男生和女生的编号,以判断他们在第几首歌时能在一起跳舞
    char quit='y';    //判断是否继续输入,如果继续输入,则输入'y';否则输入'n'
   while(quit!='n')
	{  cout<<"请输入男生和女生的编号:";
       cin>>a>>b;
       while((a>m)||(b>n))   //如果输入错误
	   {  cout<<"输入的编号过大,请重新输入:";
         cin>>a>>b;
	   }
	   charge(a,b);
 	   cout<<"是否继续(是请输入'y',否则请输入'n'):";
       cin>>quit;
	}
    return 0;
}
void Initqueue(cirularQueue<int> &Q,int m)  //初始化队列
{     for(int i=1;i<=m;i++)
       Q.push(i);
}
void display(int m,int n)
{  cirularQueue<int> man(m+1);
   cirularQueue<int> woman(n+1);
   Initqueue(man,m);
   Initqueue(woman,n);
   cout<<"请输入曲目数:";
   cin>>songnum;
   cout<<"每曲的配对情况为:"<<endl;
   for(int k=1;k<=songnum;k++)
   {  int x=0,y=0;   //男生和女生的编号
      man.Pop(x);      //男生按顺序出对跳舞
      woman.Pop(y);    //女生按顺序出对跳舞
cout<<"第"<<k<<"曲:\t"<<x<<"号男生<->"<<y<<"号女生"<<endl;  //他们在一起跳舞
     man.push(x);    //跳完舞后男生再次进入队列等在下一次跳舞
     woman.push(y);  //跳完舞后男生再次进入队列等在下一次跳舞
   }
}
void charge(int a,int b)
{ int count=0;  //定义舞曲计数以记录他们能在第几曲时在一起跳舞
  cirularQueue<int> man1(m+1);
  cirularQueue<int> woman1(n+1);
  Initqueue(man1,m);
  Initqueue(woman1,n);
  while(count<=songnum)
	  {  int x, y;
         count++;
         man1.Pop(x);
         woman1.Pop(y);
         man1.push(x);
         woman1.push(y);
         if((x==a)&&(y==b))
		 {  cout<<"第"<<count<<"首曲:\t"<<a<<"号男生<->"<<b<<"号女生"<<endl;
  		    break;
		 }
     }
   //如果他们在这个舞会上不能在一起跳舞,则输出
      if(count==songnum+1)
	  cout<<"他们在这个舞会上不可能在一起跳舞"<<endl;
}
	

    原文作者:舞伴问题
    原文地址: https://blog.csdn.net/qq_39322743/article/details/79689156
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞