合肥学院
计算机科学与技术系
课程设计报告
2009~2010学年第二学期
课程
数据结构与算法
课程设计名称
单循环赛中选手胜负序列求解问题
学生姓名
王梦宇
学号
0804012009
专业班级
08计科(2)
指导教师
张贯虹 王昆仑
2010年6月
题目:单循环赛中选手胜负序列求解问题
题目内容:有n个选手p1,p2,p3,…,pn参加了的单循环赛,每对选手之间非胜即负。现在要求求出一个选手序列p1’,p2’,p3’,…,pn’,使其满足pi’胜pi+1’(i=1,…,n-1)。
1、问题分析和任务定义
单循环赛的定义:
单循环赛,是所有参加比赛的队两两进行比赛并且每两队均能相遇一次,最后按各队在全部比赛中的积分、得失分率排列名次。如果参赛球队不多,而且时间和场地都有保证,通常都采用这种竞赛方法。
单循环比赛轮次的计算:
本题有两种不同的理解,第一个是按比赛的积分排名产生胜负序列,第二个是按比赛过程中各个选手间的胜负关系产生胜负序列,具体分析如下:
(1)按比赛中积分排名产生胜负序列:
比赛可规定各个选手之间均遭遇且只遭遇一次,比赛时胜方得1分,负方得-1分,在比赛结束时按积分排序进行排名,由此产生胜负序列关系。
(2)按比赛过程中各个选手间的胜负关系产生胜负序列:
该种方法是以过程中的胜负为标准从而产生胜负序列,当然,这种胜负序列很大的可能性是不唯一的,本程序按课程设计任务书的要求,仅求出其中的一个胜负序列关系,即是在有向图中求解出一条包含所有顶点的简单路径的问题。
2、数据结构的选择和概要设计
(1)对于第一种情况,本实验选用的数据结构是结构体。结构体中包含选手的名字,编号和胜负所得的积分。胜负序列的求解转化为了对所有选手的积分的排序问题。然后根据积分的多少从大到小输出选手的名次、选手姓名、选手编号信息。其概要设计如下:
定义了一个都文件Score.h.主要包含了以下几个功能:
1
1
★★★★欢迎进入积分处理比赛结果菜单★★★★
1 输入比赛选手的信息
2 输出比赛选手的比赛名次
3 根据选手编号查询选手的比赛名次及得分
4 根据选手姓名查询选手的比赛名次及得分
0 结束本菜单操作
*****注:第一次使用本系统时请选择1号功能*****
判断
0
3
2
1
4
使用子函数Creat()用于输入选手信息
使用子函数Order()用来根据积分对选手进行排名
使用子函数Search_num(int num)根据编号查询选手信息
使用子函数Search_name(string name)根据姓名查询选手信息
跳出循环
图1 Score函数的主框架
(2)对于第二种情况,本实验采用的数据结构是有向图,每个选手视为一个顶点,每条边视为选手之间的胜负关系,箭头指向的一方为失败方。所以胜负序列的求解就转化为了图的深度遍历问题(实际上跟有向图的深度遍历不太一样,详情请看源代码附录)。另外为了便于深度遍历有向图,本实验采用的存储结构为图的邻接矩阵存储。
主要框架如下:
Win_Fail.h
Win_Fail.h的功能
子函数Graph *Creat_Graph(int n)用于创建图
子函数Print_Graph(Graph *g,int n)用于输出矩阵
void Push(int num)用于顶点进栈
子函数Pop(int num)用于出栈
子函数intTest(Graph *g,int i,int n)用于测试
子函数voidSearch(Graph *g,int i,int n)用于深度搜索
初始化函数Init()
图2 Win_Fail.h的主框架
(3)主函数的主要框架
主菜单
主菜单
欢迎使用单循环赛中选手胜负序列求解问题程序"
本程序有以下三个功能:
1:以单循环赛中的积分排名为标准
2:以单循环赛过程中的胜负为标准
0:结束操作
Case 1:子函数Score()用于根据积分求解选手序列
Case2:子函数Process()用于根据选手之间的胜负关系求解
Case3:跳出主菜单,即程序运行结束
判断
图3 主函数功能框架
3、详细设计和编码
(1)、对于第一种情况:根据积分求解的详细设计及编码
1、定义如下数据结构的选手类型
typedef struct{ //结构体
string name; //选手的姓名
int num; //选手的编号
int score; //选手所得分数
} player;
2、全局变量的定义
player pl[max];定义全局变量,其中max为