运动会成绩统计.docx
《运动会成绩统计.docx》由会员分享,可在线阅读,更多相关《运动会成绩统计.docx(42页珍藏版)》请在冰点文库上搜索。
运动会成绩统计
数据结构课程设计
运动会成绩统计
班级0408303
学号040830307
姓名曾雪峰
指导老师高航
一、需求分析
1.任务:
参加运动会有n个学校,学校编号为1……n。
比赛分成m个男子项目,和w个女子项目。
项目编号为男子1……m,女子m+1……m+w。
不同的项目取前五名或前三名积分;取前五名的积分分别为:
7、5、3、2、1,前三名的积分分别为:
5、3、2;哪些取前五名或前三名由学生自己设定。
(m=10,w=8,n=15)
2.根据提示输入所需要的值,并且依次输入各项目的成绩,并写到文件里。
3.在出现非法输入时,提示错误并重新输入。
4.程序可完成以下功能:
1).可以输入各个项目的前三名或前五名的成绩;
2).能统计各学校总分(用链表);
3).可以按学校编号、学校总分、男女团体总分排序输出(快速、基数);
4).可按学校编号查询学校某个项目的情况;可按项目编号查询取得前三或前五名的学校。
5.测试数据:
n=15,m=10,w=8.输入前三名或者前五名由用户自身选择。
二、概要设计
1.为实现上述功能,以有序链表存储资料,以快速排序法排序。
ADTList{
数据对象:
D={ai|ai∈ElemSet,i=1,2,3,……,n,n≥0}
数据关系:
R1={|a(i-1),ai∈D,i=1,2,3,……,n}
}ADTList
2.本程序包含三个模块:
(1)主程序模块:
Voidmain(){
初始化;
接收命令;
switch{
处理命令;
}
}
(2)有序表单元模块——实现有序表的抽象数据类型;
(3)节点结构单元模块——定义有序表的节点结构。
各模块之间的调用关系如下:
主程序模块
有序表单元模块
节点结构单元模块
三、详细设计
1.元素类型、节点类型和指针类型
typedefstructFirstNode
{
ElemTypeitem;//某学校获奖的项目
ElemTypegrade;//该项目的成绩
structFirstNode*next;//链域
}FItem;
typedefstructSecondNode
{
ElemTypeschool;//学校编号
ElemTypegrade;//项目的成绩
structSecondNode*next;//链域
}School;
typedefstruct
{
ElemTypeitem;//项目编号
School*firstschool;//链域指向链表中的第一个节点
}SItem;
typedefstruct
{
ElemTypeschool;//学校编号
ElemTypeallscore;//学校总分
ElemTypeboyscore;//男生团体总分
ElemTypegirlscore;//女生团体总分
FItem*firstitem;//链域指向链表中第一个获奖项目的节点
}SchNode;
typedefstruct
{
SItema[50];
}AllItem;
typedefstruct
{
SchNodeb[20];
}AllSchool;
2.使用链式线性表存储信息,每个项目的资料为一个节点。
每存储完一个项目的资料后,新建节点,存储数据。
(1)构造链式线性表操作
if(ai=(AllItem*)malloc(sizeof(AllItem))==NULL);exit(0);
if(as=(AllSchool*)malloc(sizeof(AllSchool)==NULL));exit
(1);
(2)新建节点操作
p=(School*)malloc(sizeof(School));
q=(FItem*)malloc(sizeof(FItem));
3.主函数算法
voidmain()
{
intnum;
ElemTypeitem;
FILE*file;
file=fopen("data.txt","w");//打开输出数据文件
if(file==NULL)
{
printf("Cann'topendata.txt!
\n");
exit(0);
}
printf("参加本次运动会的学校数(1-10):
");
scanf("%d",&n);
while(n<1||n>10)//判断输入的数据是否符合要求
{
printf("您的输入有误!
请重新输入···(1-10):
");
scanf("%d",&n);
}
fprintf(file,"参加本次运动会的学校数(1-10):
%d\n",n);//文件操作
printf("本次运动会的男子项目总数(1-20):
");
scanf("%d",&m);
while(m<0||m>20)//判断输入的数据是否符合要求
{
printf("您的输入有误!
请重新输入···(1-20):
");
scanf("%d",&m);
}
fprintf(file,"本次运动会的男子项目总数(1-20):
%d\n",m);
printf("本次运动会的女子项目总数(1-20):
");
scanf("%d",&w);
while(w<0||w>20)//判断输入的数据是否符合要求
{
printf("您的输入有误!
请重新输入···(0-20):
");
scanf("%d",&w);
}
fprintf(file,"本次运动会的男子项目总数(1-20):
%d\n",m);
fclose(file);
for(;;)
{
system("cls");//清屏
printf("参加本次运动会的学校数(1-10):
%d\n",n);
printf("本次运动会的男子项目总数(1-20):
%d\n",m);
printf("本次运动会的女子项目总数(1-20):
%d\n",w);
//主菜单
printf("************************************************\n");
printf("*运动会分数统计*\n");
printf("************************************************\n");
printf("*1.录入各个项目的成绩并且存储文件*\n");
printf("*2.统计各学校的总分*\n");
printf("*3.按学校的编号排序输出*\n");
printf("*4.按学校的总分排序输出*\n");
printf("*5.按男子团体总分排序输出*\n");
printf("*6.按女子团体总分排序输出*\n");
printf("*7.按学校编号查询学校某个项目的得分情况*\n");
printf("*8.按项目编号查询获得名次的学校*\n");
printf("*0.退出*\n");
printf("************************************************\n");
printf("请输入您的选择(0-8):
");
scanf("%d",&num);
while(num<0||num>8)//判断输入的数据是否符合要求
{
printf("您的输入有误!
请重新输入···(0-8):
");
scanf("%d",&num);
}
switch(num)
{
case1:
Insertgrade();break;
case2:
Statallscore(as);break;
case3:
Schoolnum(as);break;
case4:
Allscore(as);break;
case5:
Boyscore(as);break;
case6:
Girlscore(as);break;
case7:
Schoolfind(as);break;
case8:
Itemfind(as);break;
case0:
exit(0);
}
}
}
完整的程序代码:
文件Common.h中的内容
#ifndefCOMMON_H
#defineCOMMON_H
#defineTRUE1
#defineFAlSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-2
#defineOVERFLOW-1
typedefintElemType;
#endif
文件Node.h中的内容
#ifndefNODE_H
#defineNODE_H
#include
#include
#include"Common.h"
typedefstructFirstNode
{
ElemTypeitem;//某学校获奖的项目
ElemTypegrade;//该项目的成绩
structFirstNode*next;//链域
}FItem;
typedefstructSecondNode
{
ElemTypeschool;//学校编号
ElemTypegrade;//项目的成绩
structSecondNode*next;//链域
}School;
typedefstruct
{
ElemTypeitem;//项目编号
School*firstschool;//链域指向链表中的第一个节点
}SItem;
typedefstruct
{
ElemTypeschool;//学校编号
ElemTypeallscore;//学校总分
ElemTypeboyscore;//男生团体总分
ElemTypegirlscore;//女生团体总分
FItem*firstitem;//链域指向链表中第一个获奖项目的节点
}SchNode;
typedefstruct
{
SItema[50];
}AllItem;
typedefstruct
{
SchNodeb[20];
}AllSchool;
#endif
文件Function.h中的内容
#ifndefFUNCTION_H
#defineFUNCTION_H
#include
#include
#include
#include
#include
#include"Common.h"
#include"Node.h"
voidInsertgrade();
voidStatallscore(AllSchool*);
voidSchoolnum(AllSchool*);
voidAllscore(AllSchool*);
voidBoyscore(AllSchool*);
voidGirlscore(AllSchool*);
voidSchoolfind(AllSchool*);
voidItemfind(AllSchool*);
#endif
文件Function.cpp中的内容
#include
#include
#include
#include
#include
#include"Common.h"
#include"Node.h"
#include"Function.h"
externAllItem*ai;
externAllSchool*as;
externintn;
externintm;
externintw;
//快速排序算法
intPartition(AllSchool*as,intlow,inthigh,intk)
{
//交换表中子表as->b[low...high]的记录,使枢轴记录到位,
//并返回其所在位置,此时在它之前(后)的记录均不大(小)于它
ElemTypepivotkey;
as->b[0]=as->b[low];//用子表的第一个记录作枢轴记录
switch(k)
{
case1:
pivotkey=as->b[low].allscore;//枢轴记录关键字
while(low{
while(lowb[high].allscore>=pivotkey)
--high;
as->b[low]=as->b[high];//将比枢轴记录小的记录移到低端
while(lowb[low].allscore<=pivotkey)
++low;
as->b[high]=as->b[low];//将比枢轴记录小的记录移到低端
}
case2:
pivotkey=as->b[low].boyscore;
while(low{
while(lowb[high].boyscore>=pivotkey)
--high;
as->b[low]=as->b[high];
while(lowb[low].boyscore<=pivotkey)
++low;
as->b[high]=as->b[low];
}
case3:
pivotkey=as->b[low].girlscore;
while(low{
while(lowb[high].girlscore>=pivotkey)
--high;
as->b[low]=as->b[high];
while(lowb[low].girlscore<=pivotkey)
++low;
as->b[high]=as->b[low];
}
}
as->b[low]=as->b[0];//枢轴记录到位
returnlow;
}
voidQSort(AllSchool*as,intlow,inthigh,intk)
{
//对表中的子序列as->b[low...high]作快速排序
intpivotloc;
if(low{
pivotloc=Partition(as,low,high,k);//将as->b[low...high]一分为二
QSort(as,low,pivotloc-1,k);//对低子表递归排序
QSort(as,pivotloc+1,high,k);//对高子表递归排序
}
}
voidQuickSort(AllSchool*as,intk,intn)
{
//对表作快速排序
QSort(as,1,n,k);
}
//录入某项目的成绩,并写到文件中
voidInsertgrade()
{
inti,piac;
ElemTypeitem,school;
School*p;
FItem*q;
charch;
FILE*file;
ai=(AllItem*)malloc(sizeof(AllItem));
if(ai==NULL)
exit(0);
as=(AllSchool*)malloc(sizeof(AllSchool));
if(as==NULL)
exit
(1);
for(i=1;i<=w+m;i++)
{
ai->a[i].item=i;
ai->a[i].firstschool=NULL;
}
for(i=1;i<=n;i++)
{
as->b[i].school=i;
as->b[i].firstitem=NULL;
as->b[i].allscore=as->b[i].boyscore=as->b[i].girlscore=NULL;
}
as->b[0].allscore=as->b[0].boyscore=as->b[0].girlscore=NULL;
do
{
fflush(stdin);
printf("请输入您要录入成绩的项目的编号:
");
scanf("%d",&item);
while(item<1||item>m+w)
{
//判断输入的数据是否符合要求
printf("您的输入有误!
请重新输入···");
scanf("%d",&item);
}
printf("请选择您要录入前几名\n");
printf("1.前三名2.前五名\n");
scanf("%d",&piac);
while(piac!
=1&&piac!
=2)
{
//判断输入的数据是否符合要求
printf("您的输入有误!
请重新选择···");
scanf("%d",&piac);
}
if(piac==1)//输入的是前三名
{
for(i=0;i<3;i++)
{
printf("第%d名--学校编号:
",i+1);
scanf("%d",&school);
while(school<1||school>n)
{
printf("您的输入有误!
请重新输入···");
scanf("%d",&school);
}
p=(School*)malloc(sizeof(School));
q=(FItem*)malloc(sizeof(FItem));
switch(i)
{
case0:
file=fopen("data.txt","a");//打开输出数据文件
if(file==NULL)
{
printf("Cann'topendata.txt!
\n");
exit(0);
}
fprintf(file,"项目%d:
第%d名--学校编号%d:
\n",item,i+1,school);//写到文件中
fclose(file);
break;
case1:
file=fopen("data.txt","a");
if(file==NULL)
{
printf("Cann'topendata.txt!
\n");
exit(0);
}
fprintf(file,"第%d名--学校编号%d:
\n",i+1,school);
fclose(file);
break;
case2:
file=fopen("data.txt","a");
if(file==NULL)
{
printf("Cann'topendata.txt!
\n");
exit(0);
}
fprintf(file,"第%d名--学校编号%d:
\n",i+1,school);
fclose(file);
break;
}
p->school=school;
q->item=item;
switch(i)
{
case0:
p->grade=q->grade=5;
break;
case1:
p->grade=q->grade=3;
break;
case2:
p->grade=q->grade=2;
break;
}
p->next=ai->a[item].firstschool;
ai->a[item].firstschool=p;
q->next=as->b[school].firstitem;
as->b[school].firstitem=q;
as->b[school].allscore=as->b[school].allscore+q->grade;//累计学校总分
if(item<=m)
as->b[school].boyscore=as->b[school].boyscore+q->grade;//累计男团体总分
else
as->b[school].girlscore=as->b[school].girlscore+q->grade;//累计女团体总分
}
}
if(piac==2)//输入的是前五名
{
for(i=0;i<5;i++)
{
printf("第%d名--学校编号:
",i+1);
scanf("%d",&school);
while(school<1||school>n)
{
printf("您的输入有误!
请重新输入···");
scanf("%d",&school);
}
p=(School*)malloc(sizeof(School));
q=(