基于数据结构知识解决学生搭配问题

摘  要

针对学⽣搭配问题,循环队列是⼀种重要的链式结构,其特殊性在于需附设两个指针front和rear分别指⽰对头元素及队尾元素的位置且队头和队尾相邻接。在程序的设计过程中,运⽤了各种基本的算法,有判断队空及队满,出队,⼊队等.循环队列是在队列的顺序存储结构中,除了⽤⼄组地址连续的存储单元依次存放从队列头到队列尾的元素外,尚需附设两个指针front和rear分别指⽰队列头元素和队列尾元素的位置。

关键词:学生配对  数据结构  循环队列

章  绪  论

1.1  课设主要研究问题

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

1)输出每曲配对情况;

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

1.2  课设应用的理论知识

采用队列(Queue)这一数据结构,队列是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表。循环队列是在队列的顺序存储结构中,除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素外,尚需附设两个指针 front 和 rear 分别指示队列头元素和队列尾元素的位置

第二章  课设实现过程

  1.   功能模块详细设计

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

  1.   详细设计思想 

(1)要模拟动态地显示出现题目中所要求的循环,我们要先建立两个循环 队列 SqQueue1 和 SqQueue2。

(2)将男生、女生两组人分别存入这两个队列。以实现他们的循环配对输出,这是循环队列固有的特性。

(3)利用循环队列的特性,将男女生分别进行入队列和出队列操作,且实现搭配输出。

(4)循环队列的长度分别设为男女生的个数即可。

(5)存储结构: 循环链表; 核心算法: 循环队列的入队,出队,判队满,判队空。 输入数据: 男生人数、女生人数,歌曲数量 输出数据: 每一首歌曲播放时,男生和女生搭配情况(只输出编号即可) 当要查找的男女搭配时,输出歌曲编号和他们搭配的总次数。

核心算法:循环队列的入队,出队,判队满,判队空。输入数据:男生人数、女生人数,歌曲数量

输出数据:每一首歌曲播放时,男生和女生搭配情况(只输出编号即可)当要查找的男女搭配时输出歌曲编号,和他们搭配的总次数。通过以上分析,该程序具有可行性。

 算法流程图

程序代码

//头文件
//tree.h
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define MaxSons 3
typedef char ElemType;
typedef struct node
{
    ElemType data[15];     //结点的值
    struct node *sons[MaxSons];    //指向孩子结点
}TSonNode;      //孩子链存储结构中的结点类型
typedef struct
{
    char N[15];
    char n[15];
}array;
//读取文件内容到数组R中
void ReadFile(array R[],FILE *fp,int &n)
{
     while((fscanf(fp,"%s",R[n].N))!=EOF&&(fscanf(fp,"%s",R[n].n))!=EOF)
        n++;
}
//创建一颗树
TSonNode *CreateTree(char str[],array R[],int n)
{
    TSonNode *t;
    int k,i=0,j=0;
    t=(TSonNode *)malloc(sizeof(TSonNode));
    strcpy(t->data,str);
    for(k=0;k<MaxSons;k++)
      t->sons[k]=NULL;
    while(i<n)
    {
       if(strcmp(R[i].N,str)==0)
       {
           t->sons[j]=CreateTree(R[i].n,R,n);
           j++;
       }
       i++;
    }
    return t;
}
//输出树(孩子链存储结构)
void DispTree(TSonNode *t)
{
     int i=0;
     if(t==NULL)
        printf("此树为空树!\n");
     else
     {
        printf("%s",t->data);
        if(t->sons[i]!=NULL)    //若t结点至少有一个孩子
        {
           printf("(");
           for(i=0;i<MaxSons;i++)
           {
               DispTree(t->sons[i]);
               if(t->sons[i+1]!=NULL)
                  printf(",");
               else
                  break;
           }
           printf(")");
        }
     }
}
//销毁树
void DestroyTree(TSonNode *t)
{
    if(t==NULL)
        printf("此树为空树!\n");
    else
    {
        for(int i=0;i<MaxSons;i++)
        {
            if(t->sons[i]!=NULL)
                DestroyTree(t->sons[i]);
            else
                break;
        }
        free(t);
    }
}
//查找某一结点
TSonNode *FindNode(TSonNode *t,char str[])
{
    TSonNode *p;
    if(t==NULL)
        return NULL;
    else
    {
        if(strcmp(t->data,str)==0)
           return t;
        else
        {
            for(int i=0;i<MaxSons;i++)
            {
                if(t->sons[i]!=NULL)
                {
                    p=FindNode(t->sons[i],str);
                    if(p!=NULL)
                      return p;
                }
            }
            return NULL;
        }
    }
}
//求某一结点的孩子个数
int ChildCount(TSonNode *p)
{
    int count=0;
    for(int i=0;i<MaxSons;i++)
    {
        if(p->sons[i]!=NULL)
            count++;
        else
            break;
    }
    return count;
}
//求某棵树中的叶子结点数
//本例中,叶子结点数等于班级数,一个叶子结点对应一个班级
int LeafCount(TSonNode *p)
{
    int count=0;
    if(p==NULL)
        return 0;
    else
    {
        if(p->sons[0]==NULL)
          count++;
        else
        {
            for(int i=0;i<MaxSons;i++)
            {
                if(p->sons[i]!=NULL)
                    count=count+LeafCount(p->sons[i]);
                else
                    break;
            }
        }
    }
    return count;
}
//求某棵树的叶子结点值的和
int LeafSumOfvalue(TSonNode *p)
{
    int sum=0;
    if(p==NULL)
        return 0;
    else
    {
        if(p->sons[0]==NULL)
           return atoi(p->data);
        else
        {
            for(int i=0;i<MaxSons;i++)
            {
                if(p->sons[i]!=NULL)
                   sum+=LeafSumOfvalue(p->sons[i]);
                else
                    break;
            }
        }
    }
    return sum;
}

//源文件
//exp7.cpp
#include<stdio.h>
#include<stdlib.h>
#include"tree.h"
#define MaxSize 66
int main()
{
    int n=0;
    TSonNode *t;
    array R[MaxSize];
    FILE *fp;
    if((fp=fopen("table.txt","r"))==NULL)      //以只读方式打开table.txt文件
    {
        printf("error!cannot open the file!");
        exit(1);
    }
    printf("读取文件内容存入数组R中\n");
    ReadFile(R,fp,n);
    printf("输出数组R:\n");
    for(int i=0;i<n;i++)
        printf("%s %s\n",R[i].N,R[i].n);  //输出R数组查看是否读取正确
    printf("\n由数组R创建树T,");
    t=CreateTree(R[0].N,R,n);   //创建一颗树
    printf("由括号表示输出树T:\n");
    DispTree(t);
    char str[10];
    printf("\n请输入学院名:");
    scanf("%s",str);
    printf("\n%s的专业数:%d\n",str,ChildCount(FindNode(t,str)));
    printf("%s的班级数:%d\n",str,LeafCount(FindNode(t,str)));
    printf("\n请输入学院名:");
    scanf("%s",str);
    printf("\n%s的学生数:%d\n",str,LeafSumOfvalue(FindNode(t,str)));
    printf("销毁树!\n");
    DestroyTree(t);
    return 0;
}

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

X-MTing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值