运动会分数统计系统 数据结构课程设计.docx
《运动会分数统计系统 数据结构课程设计.docx》由会员分享,可在线阅读,更多相关《运动会分数统计系统 数据结构课程设计.docx(42页珍藏版)》请在冰豆网上搜索。
运动会分数统计系统数据结构课程设计
经济学院
华信学院
课程设计报告
学院:
专业:
班级:
学号:
姓名:
运动会分数统计系统的设计与实现
一.问题描述
大学作为一个提供学生全面发展的高等教育机构,不仅要培养学生的学习能力,而且更要注重学生的德智体美全面发展。
在大学中有很多丰富多彩的比赛和活动,例如运动会,演讲比赛,歌唱比赛,书法比赛等,在比赛和竞争中,我们的这些素质和能力更容易得到培养提升。
但是比赛最后的分数统计和查询往往是举办者头疼的事情,分数的统计和查询需要快速准确,因此我们设计了这个运动会分数统计系统,以便分数的统计查询。
参加运动会的n个学校编号为1~n。
比赛分成m个男子项目和w个女子项目,项目编号分别为1~m和m+1~m+w。
由于各项目参加人数差别较大,有些项目取前五名,得分顺序为7,5,3,2,1;还有些项目只取前三名,得分顺序为5,3,2。
写一个统计程序产生各种成绩单和得分报表。
二.需求分析
系统功能描述:
(1)可以输入各个项目的前三名或前五名的成绩;
(2)能统计各学校总分;
(3)可以按学校编号或名称、学校总分、男女团体总分排序输出;
(4)可以按学校编号查询学校某个项目的情况;可以按项目编号查询取得前三或前五名的学校。
三.概要设计
3.1链表结构的ADT的定义
ADTList{
数据对象:
D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}
数据关系:
R1={|ai-1,ai∈D,i=2,…,n}
基本操作:
InitList(&L)
操作结果:
构造一个空的线性表L。
GetElem(L,i,&e)
初始条件:
线性表L已存在,1≦i≦ListLength(L)
操作结果:
用e返回L中第i个数据元素的值。
LocateElem(L,e,compare())
初始条件:
线性表L已存在,compare()是数据元素判定函数。
操作结果:
返回L中第1个与e满足关系compare()的数据元素的位序。
若这样的数据元素不存在,则返回值为0。
PriorElem(L,cur_e,&pre_e)
初始条件:
线性表L已存在。
操作结果:
若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。
NextElem(L,cur_e,&next_e)
初始条件:
线性表L已存在。
操作结果:
若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。
ListInsert(&L,I,e)
初始条件:
线性表L已存在,1≦i≦ListLength(L)+1
操作结果:
在L中第i个位置之前插入新的元素e,L是表长度加1
ListTraverse(L,visit())
初始条件:
线性表L已存在。
操作结果:
依次对L的每个数据元素调用函数visit()。
一旦visit()失败,则操作失败。
}ADTList
3.2系统功能模块设计
运动会分数统计系统
输入各学校名称
输入男子运动项目
输入女子运动项目
输入男子项目的成绩
输入女子项目的成绩
查询某校各个项目的成绩
查询某校各个项目的成绩
图3-1运动会分数统计系统功能模块图
main()
womansports(LinkList &L,int n)
循环语句依次输入每个值
ListTraverse(L,visit())
schoolname(LinkList &L,int n)
mansports(LinkList &L,int n)
循环语句依次输入每个值
ListTraverse(L,visit())
ListTraverse(L,visit())
ListTraverse(L,visit())
3.3主要函数调用关系图
图3-2系统函数调用关系图
3.4主界面设计
为了实现运动会分数统计系统,需要设计一个含有多菜单项的主控菜单子程序,以系统中各个子项目的调用,为了便用户使用本系统,本系统主控菜单的运行界面如图3-3所示。
图3-3主菜单运行界面
四.详细设计
实现运动会分数统计系统的开发,采用链表结构类型存储运动会学校名称、男子女子运动项目以及男子女子项目成绩的信息。
4.1数据类型定义
//每一个学校的信息
typedefstructLnode//结点
{
chardata[20];//学校名称
intda,d1,d2;//学校编号、学校总分、男女团体分
structLnode*next;//指向下一学校
}Lnode,*LinkList;
intsz[20];
//每一个项目的信息存取
typedefstructLnode1
{
chardata[20],data1[20],data2[20],data3[20],data4[20],data5[20];
//该项目前五名学校的名称
intda1,da2,da3,da4,da5;//该项目前五名学校的编号
structLnode1*next;//指向下一项目
}Lnode1,*LinkList1;
4.2系统子程序详细设计
输入各学校名称的算法:
//按从头到尾的顺序依次建立线性链表L1共有n个节点
voidschoolname(LinkList&L1,intn)
{
inti;
LinkListp,q;
//输入头结点信息,即输入第一个学校的名字
L1=(LinkList)malloc(sizeof(Lnode));//malloc是动态开辟存,函数返回为void型指针(指向开辟的存空间);(LinkList)定义的指针的类型;(sizeof(Lnode)malloc开辟的存空间的大小
printf("请输入这%d个学校的名字:
\n",n);
p=(LinkList)malloc(sizeof(Lnode));//指向一个有意义的地
L1->next=p;//把p的值赋给nextnext指向实际的空间p时指针
scanf("%s",&p->data);//修改空间的值,&取p的数据域的地址
//从第二个节点开始依次输入到第n个节点信息
for(i=2;i<=n;i++)//p是第一个,所以i=2从2开始先指出第一个,然后第一个在指出剩下的
{
q=p;//q指向p开辟的空间即q指向p指向的地
p=(LinkList)malloc(sizeof(Lnode));//给新开辟的空间赋值
开始
输入n个学校的名字
i=0
i>n
将第i个结点加入链表L
结束
N
Y
scanf("%s",&p->data);
q->next=p;
}
}
输入男子运动项目名字的算法:
//按从头到尾的顺序依次建立线性链表L2共有n2个节点
voidmansports(LinkList1&L2,intn2)
{
//输入第一个节点的信息,即第一个男子项目的名字
inti;
LinkList1r,s;
L2=(LinkList1)malloc(sizeof(Lnode1));
printf("请输入这%d个项目的名字:
\n",n2);
r=(LinkList1)malloc(sizeof(Lnode1));
//把新开辟的空间data1-5初始化
for(intt=0;t<20;t++)
r->data1[t]='\0';
for(t=0;t<20;t++)
r->data2[t]='\0';
for(t=0;t<20;t++)
r->data3[t]='\0';
for(t=0;t<20;t++)
r->data4[t]='\0';
for(t=0;t<20;t++)
r->data5[t]='\0';
L2->next=r;
scanf("%s",&r->data);
//从第二个节点开始输入到第n2个节点的信息
for(i=2;i<=n2;i++)
{
s=r;//s指向r指向的地
r=(LinkList1)malloc(sizeof(Lnode1));
for(intt=0;t<20;t++)
r->data1[t]='\0';
for(t=0;t<20;t++)
r->data2[t]='\0';
for(t=0;t<20;t++)
r->data3[t]='\0';
for(t=0;t<20;t++)
r->data4[t]='\0';
for(t=0;t<20;t++)
r->data5[t]='\0';
scanf("%s",&r->data);
s->next=r;
}
}
开始
输入n个男子项目的名字
i=0
i>n
将第i个结点加入链表L
结束
N
Y
输入女子运动项目名字的算法:
//按从头到尾的顺序依次建立线性链表L3共有n1个节点
voidwomansports(LinkList1&L3,intn1)
{
//输入第一个节点的信息,即第一个女子项目的名字
inti;
LinkList1r,s;
L3=(LinkList1)malloc(sizeof(Lnode1));
printf("请输入这%d个项目的名字:
\n",n1);
r=(LinkList1)malloc(sizeof(Lnode1));
L3->next=r;
scanf("%s",&r->data);
//从第二个节点开始依次输入到第n1个节点信息
for(i=2;i<=n1;i++)
{
s=r;
r=(LinkList1)malloc(sizeof(Lnode1));
scanf("%s",&r->data);
s->next=r;
开始
输入n个女子项目的名字
i=0
i>n
将第i个结点加入链表L
结束
N
Y
}
}
参加比赛的学校的总分排名的算法:
voidschoolrankings(LinkList&L1,intn)
{
LinkListp;学校的数据类型上边
intz,i,j,y;
printf("参加这次比赛的学校的总分排名:
\n");
p=L1->next;//下一个地的指针给pp是学校的数据类型p是一个节点,L1下一个节点给p
//先把每个学校的总分依次遍历,存放在数组sz中。
一个一个取,一个一个找先让p指向一个链表
for(i=0;i<=n-1;i++)
{
sz[i]=p->da;//节点的信息指向一个数组,data学校总数的数据域,把所有的学校的总分
p=p->next;
}
//再对数组sz用冒泡排序法进行从小到大排序
for(i=1;i<=n-1;i++)
{
for(j=1;j<=n-i;j++)
{
if(sz[j-1]>sz[j])
{
y=sz[j-1];
sz[j-1]=sz[j];
sz[j]=y;
}
}
}
z=1;//初始化
//把线性链表L1按项目总分从大到小的顺序排列,并打印名次
for(i=n-1;i>=0;i--)
{
p=L1->next;//L1表示一个节点,取出里面一个数据,那个数据的名字是next,next也是一个节点,p也是一个节点,
if(i>0)//意义是判断下一个是不是
//如果值相等则链表指针直接指向下一个,不用交换位置
while(sz[i]==sz[i-1])相邻的两个数组素不素相等
{
i--;//从大到小,从最后一个比较
}
//在链表L1中找到与sz[i]相等的节点的位置,并打印出名次信息
for(j=1;j<=n;j++)
{
if(sz[i]==p->da)//数组里面的值从最后一个开始取
{
printf("第%d名%s:
%d分\n",z,p->data,p->da);
z++;
}
p=p->next;
}
}
}
开始
结束
i=0
i++
i>n
Y
N
将每个学校的总分赋给数组sz[n]
对数组sz[n]进行冒泡排序
遍历链表L找到与sz[i]相等的结点并输出总分
参加这次比赛的学校的男子项目的成绩排名的算法:
//男子项目排名算法代码与上述学校总分的排名算法完全一致,其中男子项目排序的过程为比较男子项目总分
voidmanrankings(LinkList&L1,intn)
{
LinkListp;
intz,i,j,y;
printf("参加这次比赛的学校的男子项目的成绩排名:
\n");
p=L1->next;
//先把每个学校的男子项目总分依次遍历,存放在数组sz中。
for(i=0;i<=n-1;i++)
{
z[i]=p->d1;
p=p->next;
}
//再对数组sz用冒泡排序法进行从小到大排序
for(i=1;i<=n-1;i++)
{
for(j=1;j<=n-i;j++)
{
if(sz[j-1]>sz[j])
{
y=sz[j-1];
sz[j-1]=sz[j];
sz[j]=y;
}
}
}
z=1;
//把线性链表L1按男子项目总分从大到小的顺序排列,并打印名次
for(i=n-1;i>=0;i--)
{
p=L1->next;
if(i>0)
while(sz[i]==sz[i-1])
{
i--;
}
//在链表L1中找到与sz[i]相等的节点的位置,并打印出名次信息
for(j=1;j<=n;j++)
{
if(sz[i]==p->d1)
{
printf("第%d名%s:
%d分\n",z,p->data,p->d1);
z++;
}
p=p->next;
}
}
}
开始
结束
i=0
i++
i>n
Y
N
将男子项目的总分赋给数组sz[n]
对数组sz[n]进行冒泡排序
遍历链表L找到与sz[i]相等的结点并输出总分
参加这次比赛的学校的女子项目的成绩排名的算法:
//女子项目排名算法代码与上述学校总分的排名算法完全一致,其中女子项目排序的过程为比较女子项目总分
voidwomanrankings(LinkList&L1,intn)
{
LinkListp;
intz,i,j,y;
printf("参加这次比赛的学校的女子项目的成绩排名:
\n");
p=L1->next;
//先把每个学校的女子项目总分依次遍历,存放在数组sz中
for(i=0;i<=n-1;i++)
{
sz[i]=p->d2;
p=p->next;
}
//再对数组sz用冒泡排序法进行从小到大排序
for(i=1;i<=n-1;i++)
{
for(j=1;j<=n-i;j++)
{
if(sz[j-1]>sz[j])
{
y=sz[j-1];
sz[j-1]=sz[j];
sz[j]=y;
}
}
}
z=1;
//把线性链表L1按女子项目总分从大到小的顺序排列,并打印名次
for(i=n-1;i>=0;i--)
{
p=L1->next;
if(i>0)
//如果值相等则链表指针直接指向下一个,不用交换位置
while(sz[i]==sz[i-1])
{
i--;
}
//在链表L1中找到与sz[i]相等的节点的位置,并打印出名次信息
for(j=1;j<=n;j++)
{
if(sz[i]==p->d2)
{
printf("第%d名%s:
%d分\n",z,p->data,p->d2);
z++;
}
p=p->next;
}
}
}
开始
结束
i=0
i++
i>n
Y
N
将女子项目的总分赋给数组sz[n]
对数组sz[n]进行冒泡排序
遍历链表L找到与sz[i]相等的结点并输出总分
五.编码实现及系统测试
图5-1输入基本信息
图5-2学校及项目排名
图5-3查询某校各个项目的成绩
图5-4查询某个项目的比赛结果
图5-5结束本程序
六.结果分析
表6-1时间、空间复杂度
操作
时间复杂度
空间复杂度
1
O(n+m)
O
(1)
2
O(n)
O
(1)
3
O(m)
O
(1)
注:
m为学校个数,n为项目个数。
七.学习体会
通过这次数据结构课程设计,我收获了很多:
一.经过这几天的学习,进一步提升了C语言的应用能力,巩固了数据结构上课所学习的容,数据结构知识的应用能力有了一定的提升,并且对C语言和数据结构有了更深层次的认识。
二.这次课程设计我们选的课题是运动会分数统计,涉及到线性链表以及C语言的一些基本的知识。
在以前的学习中,对知识只是掌握了大概的容,基础知识掌握的不牢固,所以编写程序的过程非常的困难,通过这次课程设计,让我知道基础知识非常重要。
在进行概要设计的时候要注意结合问题的需求分析,函数调用要和系统功能相结合。
在书写程序时,要认真细心,很多错误都是因为自己的粗心,调试程序就花费了非常多的时间。
三.通过这次课程设计,让我明白了独立思考的重要性。
一个东西只有经过自己的思考,自己明白了才是真的明白了。
在思考的过程中,对一个问题思考的越深入,可以挖掘的东西就越多。
在解决问题时要结合多面的因素,不能只单面思考问题。
八.源程序清单
#include
#include
#include
typedefstructLnode类型定义
{
chardata[20];//学校名称
intda,d1,d2;//学校编号、学校总分、男女团体分
structLnode*next;//指向下一学校
}Lnode,*LinkList;
intsz[20];
//每一个项目的信息
typedefstructLnode1
{
chardata[20],data1[20],data2[20],data3[20],data4[20],data5[20];
//该项目前五名学校的名称
intda1,da2,da3,da4,da5;//该项目前五名学校的编号
structLnode1*next;//指向下一项目
}Lnode1,*LinkList1;
输入各学校名称的算法:
//按从头到尾的顺序依次建立线性链表L1共有n个节点
voidschoolname(LinkList&L1,intn)
{
inti;
LinkListp,q;
//输入头结点信息,即输入第一个学校的名字
L1=(LinkList)malloc(sizeof(Lnode));
printf("请输入这%d个学校的名字:
\n",n);
p=(LinkList)malloc(sizeof(Lnode));
L1->next=p;
scanf("%s",&p->data);
//从第二个节点开始依次输入到第n个节点信息
for(i=2;i<=n;i++)
{
q=p;
p=(LinkList)malloc(sizeof(Lnode));
scanf("%s",&p->data);
q->next=p;
}
}
输入男子运动项目名字的算法:
//按从头到尾的顺序依次建立线性链表L2共有n2个节点
voidmansports(LinkList1&L2,intn2)
{
//输入第一个节点的信息,即第一个男子项目的名字
inti;
LinkList1r,s;
L2=(LinkList1)malloc(sizeof(Lnode1));
printf("请输入这%d个项目的名字:
\n",n2);
r=(LinkList1)malloc(sizeof(Lnode1));
for(intt=0;t<20;t++)
r->data1[t]='\0';
for(t=0;t<20;t++)
r->data2[t]='\0';
for(t=0;t<20;t++)
r->data3[t]='\0';
for(t=0;t<20;t++)
r->data4[t]='\0';
for(t=0;t<20;t++)
r->data5[t]='\0';
L2->next=r;
scanf("%s",&r->data);
//从第二个节点开始输入到第n2个节点的信息
for(i=2;i<=n2;i++)
{
s=r;
r=(LinkList1)malloc(sizeof(Lnode1));
for(intt=0;t<20;t++)
r->data1[t]='\0';
for(t=0;t<20;t++)
r->data2[t]='\0';
for(t=0;t<20;t++)
r->data3[t]='\0';
for(t=0;t<20;t++)
r->data4[t]='\0';
for(t=0;t<20;t++)
r->data5[t]='\0';
scanf("%s",&r->data);
s->next=r;
}
}
输入女子运动项目名字的算法:
//按从头到尾的顺序依次建立线性链表L3共有n1个节点
voidwomansports(LinkList1&L3,intn1)
{
//输入第一个节点的信息,即第一个女子项目的名字
inti;
LinkList1r,s;
L3=(LinkList1)malloc(sizeof(Lnode1));
printf("请输入这%d个项目的名字:
\n",n1);
r=(LinkList1)malloc(sizeof(Lnode1));
L3->next=r;
scanf("%s",&r->data);
//从第二个节点开始依次输入到第n1个节点信息
for(i=2;i<=n1;i++)
{
s=r;
r=(LinkList1)malloc(sizeof(Lnode1));
scanf("%s",&r->data);
s->next=r;
}
}
参加比赛的学校的总分排名的算法:
voidschoolrankings(LinkList&L1,intn)
{
LinkListp;
intz,i,j,y;
printf("参加这次比赛的学校的总分排名:
\n");
p=L1->next;
//先把每个学校的总分依次遍历,存放在数组sz中。
for(i=0;i<=n-1;i++)
{
sz[i]=p->da;
p=p->next;
}
//再对数组sz用冒泡排序法进行从小到大排序
for(i=1;i<=n-1;i++)
{
for(j=1;j<=n-i;j++)
{
i