数据结构我的课程设计说明书.docx
《数据结构我的课程设计说明书.docx》由会员分享,可在线阅读,更多相关《数据结构我的课程设计说明书.docx(31页珍藏版)》请在冰豆网上搜索。
数据结构我的课程设计说明书
摘要
学生成绩管理涉及到的算法都是以链表或顺序表的基本运算作为基础的,此程序包括:
添加学生成绩,查询学生成绩,修改学生成绩,,删除学生成绩,求各科平均分,根据学生各科成绩平均分排序,
查询学生所有成绩输出显示的功能。
通过链表存储结构实现数据的输入,实现各子程序过程的演示,对异常输入信息报错。
关键词:
学生成绩管理的演示:
学生成绩管理库的建立,学生成绩的删除,查找,添加,修改和排序,学生添加删除,修改查询,以及添加课程。
前言
很多涉及学生成绩管理操作的算法都是以链表操作为基础,通过链表的建立,结点添加、查询与删除的演示,方便在学习中更好的理解链表结点的添加、查询、删除的过程。
通过对链表的建立,结点添加、查询与删除的演示,我们在对一些问题进行求解时,会发现有些问题很难找到规律,或者根本无规律可寻。
对于这样的问题,可以利用计算机运算速度快的特点,先搜索查找所有可能出现的情况,再根据题目条件从所有可能的情况中,删除那些不符合条件的结点。
在链表的建立算法中,在链表的第一个结点之前附设一个结点,称之为头结点。
头结点的数据域可以不存储任何信息,也可存储如线性表的长度等类的附加信息,头结点的指针域存储指向第一个结点的指针。
在插入结点的过程中,首先要生成一个数据域为X的结点,然后插入在链表中。
根据插入操作的逻辑定义,还需要修改结点的指针域。
在删除结点的过程中,首先查找到要删除的结点,然后删除,再修改结点的指针域。
总之,在一单链表中插入或删除一个结点算法实现时,仅需修改指针而不需要移动元素,因此它没有顺序存储结构所具有的弱点,所以在计算机实现多种算法中得到了广泛的应用。
正文
1.问题描述
该设计要求学生以算法与数据结构课程成绩管理为背景,设计出一个简单的能够实现成绩管理功能的系统。
通过该题目的设计过程,可以加深理解线性表、查找表的逻辑结构、存储结构,掌握查找、排序等基本运算的实现,进一步理解和熟练掌握课本中所学的各种数据结构,学会如何把学到的知识用于解决实际问题,培养学生的动手能力。
2.采用类c语言定义相关的数据类型
学生成绩管理系统的功能实现如下:
A.使用链表存储结构实现数据的输入
B.使用顺序查找实现各数据的查找
C.根据文字提示进行功能调用
D.对有异常的输入报错并重新输入
(1)定义学生课程结构体的链表:
structkecheng{
charkechengname[10];
floatdata;
structkecheng*next;
};
(2)定义学生结构体的链表:
structstudent1{
charclassname[9];
charname[9];
charnumber[9];
kecheng*ke;
};
(2)定义操作对象结构体的链表:
typedefstructstudent2{//建立操作对象结构体
student1stu;
structstudent2*next;
}student2,stud;
3.各模块的伪码算法
1.添加学生
voidstudent:
:
input()//增加学生至连表尾
{
stud*p;
system("cls");
intj=0;
stud*s;
if(head!
=NULL)//判断头指针是否为空
{
p=head;
while
(1)
{
if(p->next==NULL)
break;
p=p->next;
}
}
charflag='y';
while(flag=='y')//创建连链表
{
s=(stud*)malloc(sizeof(stud));s->next=NULL;s->stu.ke=initkecheng();
cout<<"班级"<<""<<"姓名"<<""<<"学号"<<"";//输入提示信息
kecheng*p1;p1=s->stu.ke;
while
(1)
{
cout<kechengname<<"";
p1=p1->next;
if(p1->next==NULL)
break;
}
cout<cin>>s->stu.classname>>s->stu.name>>s->stu.number;//输入信息
p1=s->stu.ke;
while
(1)
{
cin>>p1->data;
p1=p1->next;
if(p1->next==NULL)
break;
}
if(head==NULL)
head=s;
else
p->next=s;
p=s;
j++;
p1=s->stu.ke;floattotal;inti;total=0;i=0;
while
(1)
{
total+=p1->data;
p1=p1->next;i++;
if(p1->next==NULL)
break;
}
p1->data=total/(i*1.0);
cout<<"Iscontinue?
y/n"<flag='n';
cin>>flag;
}
cout<<"您这次一共输入了"<if(j==0){_sleep(1000);return;}
}
2.删除学生
voidstudent:
:
del(charnumber[])//完成删除学生
{
if(!
panduannum(number))
return;
if(head==NULL)
{
cout<<"非法,请确认有信息可以删除!
"<getch();
return;
}
stud*p,*q;
p=head;
charflag='y';
inti=0,j=0;
while
(1)
{
flag='y';
for(i=0;i<8;i++)
{
if(number[i]!
=p->stu.number[i])
flag='n';
}
if(flag=='y'){j=1;break;}
else
{
if(p->next==NULL)
break;
p=p->next;
}
}
if(!
j)
{
cout<<"没有学号为"<"<}
stud*s;
s=(stud*)malloc(sizeof(stud));
studcopy(s,p);
output(s);cout<q=head;
if(q==p)
head=head->next;
else
{
while(q->next!
=p)
q=q->next;
q->next=p->next;
}
cout<<"是否确认删除学生?
y/n"<charch;
cin>>ch;
if(ch=='y')
{
savefile(head);
cout<<"已成功保存文件!
"<getch();
}
else
readfile();
}
3.修改学生
voidstudent:
:
modify(charnumber[])
{
if(!
panduannum(number))
return;
if(head==NULL)
{
cout<<"非法,请确定您已将信息成功导入!
"<return;
}
stud*p,*q;
p=head;
charflag='y';
inti=0,j=0;
while
(1)
{
flag='y';
for(i=0;i<9;i++)
{
if(number[i]!
=p->stu.number[i])
flag='n';
}
if(flag=='y'){j=1;break;}
else
{
if(p->next==NULL)
break;
p=p->next;
}
}
if(!
j)
{
cout<<"没有学号为"<"<}
q=(stud*)malloc(sizeof(stud));
studcopy(q,p);
output(q);cout<cout<<"请输入修改信息!
"<kecheng*p1;
p1=p->stu.ke;floattotal=0;i=0;
while
(1)
{
cout<kechengname<<":
";
cin>>p1->data;
total+=p1->data;
p1=p1->next;i++;
if(p1->next==NULL)
break;
}
p1->data=total/(i*1.0);
studcopy(q,p);
output(q);
savefile(head);
cout<<"已成功将修改后信息自动保存至文件!
"<}
4.对单科低分学生查询
stud*student:
:
loworder(inti,unsignedintj)
{
kecheng*p1,*kep1,*kep2;
p1=initkecheng();charkechengname[10];intx=1;
while
(1)//确定排序课程
{
if(x==i)
{strcpy(kechengname,p1->kechengname);break;}
p1=p1->next;
x++;
}
stud*p,*pa,*m,*head1,*p2,*t,*s,*q;inttotalmember=0;
p=head;
head1=(stud*)malloc(sizeof(stud));head1->next=NULL;
pa=(stud*)malloc(sizeof(stud));pa=NULL;
while
(1)//建立连表
{
p1=p->stu.ke;
while
(1)//查找课程
{
if(stringequal(p1->kechengname,kechengname))
break;
p1=p1->next;
}
if(p1->data<=j)//建立链表
{
s=(stud*)malloc(sizeof(stud));
studcopy(s,p);
if(pa==NULL)
pa=s;
else
q->next=s;
q=s;totalmember++;
}
if(p->next==NULL)
break;
p=p->next;
}
if(pa==NULL)
{
head1=NULL;
returnhead1;
}
m=pa;
i=totalmember;
while
(1)//完成排序
{
charflag;
flag='n';
t=(stud*)malloc(sizeof(stud));
studcopy(t,m);
if(head1->next==NULL)
{
head1->next=t;
}
else
{
p2=head1->next;
kep1=t->stu.ke;kep2=p2->stu.ke;
while
(1)
{
if(stringequal(kep1->kechengname,kechengname))
break;
kep1=kep1->next;kep2=kep2->next;
}
if(kep1->data>=kep2->data)
{
head1->next=t;
t->next=p2;
}
else
{
while
(1)
{
kep1=t->stu.ke;kep2=p2->stu.ke;
while
(1)
{
if(stringequal(kep1->kechengname,kechengname))
break;
kep1=kep1->next;kep2=kep2->next;
}
if(kep1->data>=kep2->data)
break;
if(p2->next==NULL)
{
flag='y';break;
}
p2=p2->next;
}
if(flag=='y')
p2->next=t;
else
t->next=p2->next;p2->next=t;
}
}
if(m->next==NULL)
break;
m=m->next;
}
head1=head1->next;
returnhead1;
}
5.对所有有课程低分学生查询
stud*student:
:
totalorder(unsignedinti)//完成对有低分的学生的处理
{
if(head==NULL)
returnhead;
stud*p,*q,*r,*s;
kecheng*p1;
charflag='n';
inttotalnumber=0;
inttotalmember=0;
intmember=0;
floatpercent=0;
p=(stud*)malloc(sizeof(stud));p=NULL;
q=(stud*)malloc(sizeof(stud));q=NULL;
r=(stud*)malloc(sizeof(stud));
r=head;
while
(1)//建立连表并统计信息
{
flag='n';
p1=r->stu.ke;
while
(1)
{
if(p1->data<=i)
{flag='y';totalnumber++;}
if(p1->next==NULL)
break;
p1=p1->next;
}
if(flag=='y')
{
s=(stud*)malloc(sizeof(stud));s->next=NULL;
studcopy(s,r);
if(p==NULL)
p=s;
else
q->next=s;
q=s;
totalmember++;
}
member++;
if(r->next==NULL)
break;
r=r->next;
}
//输出统计信息
cout<p1=initkecheng();intx=1;intj;inttotalkecheng=0;
while
(1)
{
j=lowkechengnumber(x,i);
cout<kechengname<<"低于等于"<totalkecheng+=j;
if(p1->next->next==NULL)
break;
p1=p1->next;x++;
}
cout<<"总的低于"<
percent=(totalmember*1.0)/(member*1.0);percent=percent*100;
cout<<"所有学生一共"<"<percent=totalkecheng*1.0/(member*x);percent=percent*100;
cout<<"所有课程数为"<"<"<cout<returnp;
}
6.查询低平均分学生并排序
stud*student:
:
lowaverage(floati)
{
kecheng*p1;p1=initkecheng();
intt=0;floatj;
while
(1)
{
t++;
if(p1->next==NULL)
break;
p1=p1->next;
}
returnloworder(t,i);
}
7.查询挂科学生
voidstudent:
:
guake(inti)//对挂科学生的处理
{
intt=0,n=0;
stud*p,*s,*head1,*q;kecheng*p1;
head1=(stud*)malloc(sizeof(stud));head1=NULL;
p=head;
while
(1)
{
t=0;
p1=p->stu.ke;
while
(1)
{
if(p1->data<60)
t++;
if(p1->next->next==NULL)
break;
p1=p1->next;
}
if(t==i)//判断该学生挂科数是否满足条件
{
s=(stud*)malloc(sizeof(stud));
studcopy(s,p);
if(head1==NULL)
head1=s;
else
q->next=s;
q=s;
n++;
}
if(p->next==NULL)
break;
p=p->next;
}
cout<<""<<"现在输出挂了"<
output(head1);cout<cout<<""<<"一共有"<getch();
}
4.函数的调用关系图
5.调试分析和测试结果
A.调试程序时,遇到指针循环指向自己,导致程序无法继续运行,主要原因是操作时没有将指针完全断开,后添加studcopy(p,q)函数,将操作链表中的q信息复制到p中并将p->next=NULL.再将调试之后,程序通过。
B.算法的时间复杂度和空间复杂度
A.成绩信息的添加、查询、修改、删除、求平均分时间复杂度都为:
O(n)
B.成绩信息的排序时间复杂度为:
O(n!
)
C.成绩信息的空间复杂度为:
1164KB
6.软件使用说明书
1.输出学生成绩管理系统主菜单项
2.添加学生
3.删除学生
4.修改学生成绩
5.查询学生成绩
7.显示所有学生信息
8.显示统计信息菜单
9.对单科低分学生查询
9..对所有有课程低分学生查询
10.查询低平均分学生并排序
11.查询挂科学生
设计总结
在这三周的数据结构课程设计中,我的题目是:
学生成绩管理系统。
这个设计是一个比较综合的练习,它主要用到链表、查找等相关知识。
这三周课程设计中,通过该题目的设计过程,我加深了对链表的理解,对链表结点的添加、查找、删除基本运算的实现有所掌握,对课本中所学的各种数据结构进一步理解和掌握,学会了如何把学到的知识用于解决实际问题,锻炼了自己动手的能力。
在三周的课程设计中我遇到了很多的问题,我认识到一个人要完成所有的工作是非常困难和耗时的。
这些问题在老师和同学许永锋帮助、和对各种资料的查阅下,得到了解决。
这次课设培养了我自主动手,独立研究的能力,和团队合作的工作方法,在以后的学习中我会更加注意各个方面的能力的协调发展,为今后在学习工作中能更好的发展打下了坚实的基础。
三周的课程设计很短暂,但其间的内容是很充实的,在其中我学习到了很多平时书本中无法学到的东西,积累了经验,锻炼了自己分析问题,解决问题的能力,并学会了如何将所学的各课知识融会,组织,来配合学习,三周中我收益很大,学到很多。
我相信如果时间更充裕我会把这次的课程设计做得更加完善。
参考文献
1.严蔚敏,吴伟民.《数据结构题集(C语言版)》.清华大学出版社.
2.陈维兴,林小茶,《C++面向对象程序设计教程》,清华大学出版社.
致谢
首先感谢我的指导老师张永老师,他在我的课程设计过程中提出了指导性的方案和架构,并指引我阅读相关的资料和书籍,使我在不熟悉的领域中仍能迅速掌握新的技术。
感谢我的数据结构老师张永老师和C++语言老师朱昌盛老师在以往的基础课学习中为我打下良好的基础,这是我这次课程设计能够顺利完成的前提。
我的同学在设计完成后对程序的测试,没有他们,也许就难以发现一些潜在的错误,在此一并表示感谢。
附件Ⅰ基本算法实现
归并算法及应用
//归并排序算法的实现.cpp:
Definestheentrypointfortheconsoleapplication.
//
#include"stdafx.h"
#include"stdio.h"
#defineMAXSIZE50//顺序表最大长度
typedefintkeytype;//自定义关键字类型为整型
typedefintelemtype;
typedefstruct//定义记录类型
{
keytypekey;
elemtypeotheritem;
}recdtype;//记录结点类型
recdtyper[MA