1. 需求分析
【编程解决的问题】
参加运动会有 n 个学校,学校编号为 1……n。比赛分成 m 个男子项目,和
w 个女子项目。项目编号为男子 1……m,女子 m+1……m+w。不同的项目取前
五名或前三名积分;取前五名的积分分别为:7、5、3、2、1,前三名的积分分
别为:5、3、2; (m<=20,n<=20)
【问题需求】
本程序中,当运行时,由用户自己定义是取前三名还是取前五名, 然后进
入相应主界面来选择自己所需要的功能, 每个学校的参赛获奖 项目数可由每个
学校的输入不同项目得分情况而决定。 对于每个学校 总分、排序和查询等功能
可以通过选择菜单中不同的编号来实现。
【基本要求】
(1)可以输入各个项目的前三名或前五名的成绩;
(2)能统计各学校总分,
(3)可以按学校编号或名称、学校总分、男女团体总分排序输出;
(4)可以按学校编号查询学校某个项目的情况;可以按项目编号查询取得前三
或前五名的学校。
(5)存储结构自选,但要求运动会的相关数据存入并能随时查询
(6)规定:输入数据形式和范围:可以输入学校的名称,运动项目的名称
(7)输出形式:有中文提示,各学校分数为整形
(8)界面要求:有合理的提示,每个功能可以设立菜单,根据提示,可以完成
相关的功能要求。
【测试数据】
·学校信息
学校编号
1
2
3
4
5
6
7
8
学校名称
北京大学
南京大学
武汉大学
上海理工大学
学校成绩
12
18
5
0
17
7
苏州科技大学
哈尔滨理工大学 8
哈尔滨工业大学 17
长沙理工大学
男团成绩
7
12
2
0
10
0
5
10
女团成绩
5
6
3
0
7
7
3
7
·项目信息
前几名
5
3
5
3
5
3
性别
1
0
0
1
1
0
项目编号
1
2
3
4
5
6
项目名称
乒乓球
跳水
花样滑冰
铅球
400 米自由泳
撑杆跳
获奖学校编号
8
6
8
1
2
5
2. 概要设计
typedef struct school {
int schoolId;
char* schoolName;
int schoolGrade;
int manGrade;
int womanGrade;
struct school* next;
}Node;
typedef struct program {
int programId;
char* programName;
int sex;
int power;
int school[100];
struct program* next;
}PNode;
//学校编号
//学校名称
//学校总分
//男团分数
//女团分数
//项目编号
//项目名称
//性别
//积分方式
//获奖学校
char* GetString();
char Getchar();
void PrintMenu();
void GetSchoolNode(Node** pHead, Node** pEnd);
void GetProgramNode(PNode** pHead, PNode** pEnd);
void IntiInfo(Node** pHead, Node** pEnd, PNode ** ppHead, PNode **
//读入变长字符串
//清空 stdin
//主菜单
//链表添加结点
//链表添加结点
//初始化学校信息,构建链表
//输入数字检测
int CheckNum(int* num, int max, int min);
void InitGrade(PNode * pnode, Node* pHead, int i);//初始化项目成绩信息
void AddSchoolGrade(Node* pHead, PNode* pNode, int id, int sort);
void PrintGrade(Node* pHead);
void PrintProgram(Node* pHead, PNode* pNode);// 打印项目以及取得名词的
//按照学校编号输出分数
ppEnd);
学校
//链表关键字排序
void ManGradeSort(Node** pHead);
void WomanGradeSort(Node** pHead);
void SchoolGradeSort(Node** pHead);
void Sort(Node** pHead);
//文件读写
void SFileRead(Node ** pHead, Node** pEnd);
void SFileWrite(Node* pHead);
void PFileRead(PNode ** ppHead, PNode ** ppEnd);
void PFileWrite(PNode* ppHead);
void Fun_7(PNode** ppHead, PNode** ppEnd, Node** pHead, Node** pEnd);
void Fun_8(Node* pHead, PNode* ppHead);
main 函 数 调 用 InitInfo , PrintGrade , PrintProgram , SFileRead &
PFileRead, SFileWrite & PFileWrite 等,当输入对应的值时调用相应的子函数,
而各个子函数是相互独立的。
学
校
信
息
结
构
体
1. 学校编号
2. 学校名称
3. 总成绩
4. 女团成绩
5. 男团成绩
6. 结构体指针(next)
next)
项
目
信
息
结
构
体
1. 项目编号
2. 项目名称
3. 项目权重(power)
4. 项目性别(sex)
5. 获得名次学校
6. 结构体指针(next)
3. 详细设计 实现概要设计中定义的所有数据类型,对每个操作只需要写
出流程或伪码算法;对主程序和其他模块也都需要写出流程或伪码算法(伪码算
法达到的详细程度建议为:按照伪码算法可以在计算机键盘直接输入高级程序设
计语言程序);画出函数的调用关系图。给出所使用的基本抽象数据类型,所定义
的具体问题的数据类型,以及新定义的抽象数据类型。设计出良好的输入输出界
面(清晰易懂)。
Main 函数
InitInfo 输入信
息构造链表
xxSort 链 表
关键字排序
PrintGrade & PrintProgram
打印分数以及项目详情
SFileWrite & PFileWrite
以.txt 格式保存当前信息
SFileRead & PFileRead
读取路径下的文件
CheckNum 检查输入
是否符合规范
GetString 读 入 变
长的字符串
InitInfo 函数:
输入学校个数 m
输入项目个数 n
j < n
否
j = 0
是
i < m
i = 0
是
输入 n 个项目名称
及成绩 j++
否
输 入 m 个 学 校 的
名称 i++
项目及学校编号自动生成
项
目
信
息
结
构
体
回到主菜单
创建 Program 链表
创建 School 链表
学
校
信
息
结
构
体
单链表(无头结点)
SortList 函数:
选择相应的关键字 Key(总成绩&女
团成绩&男团成绩)
标志结点 == NULL
排序结束
遍历链表
标志结点 != NULL
调 用 PrintGrade
输出成绩
以 Key 的值使用基于 Bubble Sort 的
排序方式交换结点方式排序单链表
当 交 换 结 点
为 头 结 点 时
需特殊处理
单链表排序示意图:
!=NULL
SFileWrite & PFileWrite 函数:
确定文件路径(默认为
当前目录).txt 格式
以"w+"的形式打开文件(若无
文件则创建 若有则覆盖)
false
ERROR:文件创
建失败 exit(0)
fscanf 将数据写入文件
标志结点!= NULL
true
使用 while 遍历链表
标志结点== NULL
文件写入结束 退出程序
SFileRead & PFileRead 函数:
确定文件路径(默认为
当前目录).txt 格式
以"r"的形式打开文件(仅
可对文件操作)
false
ERROR:文件打开失
败 返回主菜单
返回主菜单
是
分别创建学校 &项目链表
将数据存入结点
true
true
判断是否重复读入数据
!= EOF
false
fprintf 读取数据
== EOF
数据读取成功 返回主菜单
4. 调试分析 内容包括:
(a)调试过程中遇到的问题是如何解决的以及对设计与实现的回顾讨论和分
析;
(b)算法的时空分析(包括基本操作和其他算法的时间复杂度和空间复杂度的
分析)和改进设想;
(c)经验和体会等。
通过本次数据结构课程设计
5. 用户使用说明
采用了用户交互式界面设计,因此只需要根据 DOS 的提示进行操作即可使
用
菜单界面
6. 测试结果
【测试数据输入】
进入用户界面,使用 1 功能添加学校及项目信息
添加学校名称
添加项目信息
录入项目获奖学校
输入错误数据时的检查
录入完成回到主菜单
【函数功能测试】
排序输出功能
项目及获奖学校总览
【文件读写功能】
存储文件读入
读入异常判断