数据结构课程设计论文(2) - 图文

更新时间:2024-05-22 22:11:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

桂林电子科技大学课程设计

编号:

数据结构与算法课程设计

说明书

题目:学生成绩管理系统

学 院:计算机科学与工程学院 专业:计算机科学与技术 学生姓名: 学号: 指导教师:

2012年 09 月 21 日

桂林电子科技大学课程设计

摘要

随着科学的发展和社会的进步,许多过去由人工处理的繁杂事务开始交付计算机来完成。明显地加快了经济信息化和社会信息化的进程。因此,计算机教育在各国备受重视,计算机知识与能力已成为21世纪人才素质的基本要素之一。 本说明书简单叙述了学生管理系统的现状,重点介绍了学生成绩管理系统的实现过程:包括系统分析、数据流程分析、功能设计、系统实现、系统测试和调试。 C语言是一种通用的程序设计语言,C语言在很多方面继承和发展了以往许多高级程序设计语言的成果经验与特色,具有适应性强、应用范围广、书写格式自由、数据类型丰富、数据结构系统化、运行程序质量高、可移植性好和运行效率高等优点。而《数据结构与算法》则是对数据进行一定的结构化,通过运用各种算法使系统的实现更简便易行。

关键词:C语言;数据结构;学生成绩管理系统;

桂林电子科技大学课程设计

目录

1 系统概述 ........................................... 1 2 需求分析 ........................................... 2 2.1 数据需求分析 ................................... 2 2.2 功能需求分析 ................................... 2 2.3 界面需求 ....................................... 3 2.4 输入输出形式 ................................... 3 2.5 开发环境 ....................................... 3 3 详细设计 ........................................... 3 3.1 系统结构 ....................................... 3 3.2 各个模块的功能 ................................. 4 3.2.1 模块功能的设计 ............................. 5 3.3 数据结构设计 .................................. 19 3.3.1 学生成绩信息结构体......................... 19 3.3.2 单链表node结构体 ......................... 19 4 测试结果 .......................................... 20 5 结论 .............................................. 23 参考文献 ............................................. 24

引言

背景:21世纪,科学技术突飞猛进,特别是信息技术和网络技术的迅速发展,各个学校的规模也随之不断增大,有关学生成绩管理工作所涉及的数据量越来越大,如若进行的仍是手工的学生成绩管理,学校就不得不靠增加人力、物力来进行学生成绩管理。即使如此,手工管理仍具有效率低、管理复杂和易出错等诸多问题。所以在学校这样一个具有超大数据量的机构中,通过应用信息技术和网络技术对学生成绩信息进行系统化的管理是必须的。将计算机这一信息处理器应用于学生的个人信息管理已是势必所然,而且这也将为学生信息管理带来前所未有的改变。采用计算机对学生的信息管理是信息科学化和现代的重要标志,它也给各大高校带来了明显的社会效益。主要体现在:极大地提高了管理工作人员的工作效率,大大地减少了以往的资料室所存在的各种弊端,同时也加强和规范学校对于学生信息的管理。

目的:本系统运用C语言进行开发,C语言能够简单地进行编译一些程序,来实现对问题的解决。它能够呈现出清晰的界面,使人们能够很好地理解,并能在一些方面给人们更好的服务,所以,它能够被大多数用户所接受。经过一个学期对《数据结构与算法》的学习,我们都学到了不少东西,可能学得还不够透彻,但无论如何这都为我们以后的学习打下一定坚实的基础。在通过运用结构体和调用各种数据结构算法与C语言相结合来完成下面的学生成绩管理系统,一方面是为了检查我们一个学期以来的学习成果,另一方面是为了更进一步对数据结构与算法的掌握和运用,同时也让我们清楚的知道自己的掌握水平和不足之处。

1 系统概述

学生成绩管理系统的主要功能是实现学生成绩信息的管理。如若还没有建立文件可以在指定路径新建文件,学生成绩信息有学号、姓名、C++、高数、英语、总分、平均分和名次的显示。学生成绩管理包括对学生各科成绩的录入、查询、删除、修改、插入、统计、排序和保存等功能。查询分为按学号和按姓名进行查找,然后输出查找学生的全部信息;删除可以通过按姓名或者学号先进行学生信息记录定位,然后进行删除,最后对学生信息记录进行调整并保存;在进行修改处理时,系统会首先根据用户的要求先查找到此学生的记录,然后提示修改学号之外的值;插入学生记录,系统首先进行对插入结点位置的定位,然后在该结点后插入新的结点;统计可以对学生信息记录统计出各科不及格人数,单科及总分最高分的学生信息记录,并输出相关信息;学生信息记录排序处理,系统按照插入排序算法实现单链表的按总分字段的降序排序,并显示结果。

以上就是对本系统的整个流程和功能的大概描述,管理系统界面简洁、清楚、功能齐全,使用方便,让使用的人一看就知道如何操作。

1 / 25

2 需求分析

随着社会的发展,管理信息系统在各行各业都越来越重要,特别是教育事业。在经济发达的国家,许多教育机构都投入了大量的资金来开发信息管理系统,就是为了在以后激烈的竞争中立于不败之地。

在我国,民办教育是一个新兴的行业,它是随着改革开放和中国特有的国情发展起来的。中国民办教育促进法的出台,从一定程度上促进和规范了民办教育事业的发展,这是一个很有前途的新兴产业。与发达国家相比,我国的民办教育机构信息技术的应用程度还比较低,信息管理系统能从各方面提高工作效率,为教育机构取得良好的经济效益和社会效益。

近年来,虽然计算机技术发展迅速,网络已经普及到寻常百姓家庭,但是还有些学校还没有学生的成绩管理系统,所有的信息操纵基本都是手工完成,甚至有的还停留在纸介质基础上,这种种的管理手段会浪费许多的人力和物力,并且效率低下。现在已经进入21世纪,以后的社会是信息的社会,信息只有快、准、精才能实现其价值。传统的管理方法必然被计算机信息管理系统所替代,因为机器代替人力是必然的历史发展趋势。

设计该学生成绩管理系统具有重要的意义:学生成绩管理是学校管理中最重要的一个环节,作为学校,除了育人,就是育知,学生成绩管理的计算机化是整个教务管理的重要部分。能否实现这一步关系到学校整体办学效率的高低,应用该系统可以减少学校工作人员的工作量,缩小开支,提高学校的整体工作效率。

2.1 数据需求分析 本系统的主要数据是学生的成绩信息,学生成绩信息包括:数据类型为字符型的学生学号,姓名;数据类型为整型的C++成绩,高数成绩,英语成绩,总分和名次;还有数据类型为浮点数类型的平均分等。

2.2 功能需求分析

1. 使用中文菜单,界面设计和用户输入输出要人性化些。

2. 将学生信息保存在文本文档中,具体对学生信息进行插入删除查询操作时,将保存在

文本文档中的学生信息提取出来,保存在自己定义的数据结构中,然后再对该数据结构进行操作,所有操作完成,或者在相应的命令后,再将学生信息保存到文本文档中。 3. 具有数据输入功能,输入的数据能最终保存在文件中。 4. 具有数据删除功能,能最终从文件中删除。 5. 排序功能,根据自己设计的数据结构。

6. 具有多种查询(如按学号查询、按姓名查询等)及相关信息的输出功能;

7. 其它功能(如各种统计,统计每个学生所有课程的平均分,统计某门课程所有学生的

2 / 25

平均分等)。

8. 学生信息的修改(比如修改学生姓名,修改学生某门课程的成绩等,并将修改的结果

存储在文件中)

2.3 界面需求

系统界面要具有广泛的实用性,便于移植。界面友好,操作简便。根据软件的使用环境、用户的要求,系统界面应该简单、友好、易于使用、方便查看、简洁明快。而且系统是在Windows环境下的应用软件,软件产品的界面应该与操作系统的界面相切合,产品的主界面应该功能齐全,分类明确,让用户一眼看去就能明白大致的功能。 2.4 输入输出形式

本系统是一个学生成绩管理系统,采用VC6.0编译器作为开发环境,这个环境是我们在学习C++的平台。输入数据类型主要是char、int、float等数据类型,输入内容包括:学号、姓名、C++成绩、高数成绩、英语成绩等数据。用户在输入学生数据时不需要保证输入数据格式的正确性,系统会自动检测输入的数据是否正确,输出形式与输入形式类似,根据需要可以选择显示输入的各项内容,还可以选择显示计算好平均分后并排序后的记录,显示内容包括:学号、姓名、C++成绩、高数成绩、英语成绩、总分、平均分等数据。

2.5 开发环境

Visual C++不仅仅是是一个C++编译器,而是一个基于Windows操作系统的可视化集成开发环境IDE,这种环境开发出来的软件稳定性好、可移植性强,可以编制各种各样的Windows应用程序。

3 详细设计 3.1 系统结构 此学生成绩管理系统主要利用单链表实现,从整体结构看,分为五大功能模块:输入记录模块、查询记录模块、更新记录模块、统计记录模块和输出记录模块。其系统模块构成如图3-1所示。

3 / 25

从文件读入

输入记录模块

从键盘输入按学号查询

查询记录模块

按姓名查询

修改记录

删除记录

更新记录模块

学生成绩管理系统

插入记录

排序记录

总人数统计

统计记录模块

不及格人数统计各科最高分统计

输出记录模块输出到界面

图3-1 学生成绩管理系统功能模块图

3.2 各个模块的功能

为了满足系统需求要求,系统所需的主要模块与功能如下:

(1) 输入记录模块。输入记录模块主要完成将数据存入单链表中的工作。在此成绩管

理系统中,记录可以从以二进制形式存储的数据文件中读入,也可以从键盘逐个输入学生记录。学生记录由学生的基本信息和成绩信息字段构成。当从数据文件中读入记录时,它就是以记录为单位存储的数据文件中,将记录逐条复制到链表中。

(2) 查询记录模块。查询记录模块主要完成在单链表中查找满足相关条件的学生记录。

在此成绩管理系统中,用户可以按照学生的学号或姓名在单链表中进行查找。若找到该学生的记录,则返回指向该学生记录的指针;否则,返回一个值为NULL的空指针,

4 / 25

并输出没有找到该学生的信息。

(3) 更新记录模块。该模块主要完成对学生记录的维护。在此系统中它实现了对学生

记录的修改、删除、排序和插入等操作。而进行了这些操作之后,需要将更新后的数据保存到数据文件中。

(4) 统计记录模块。完成了对学生总人数、各科不及格人数的统计,单科成绩最高分

以及总分最高分的统计

(5) 输出记录模块。该模块主要完成两个任务:一是实现对学生记录的存盘操作,即

将单链表中的各节点中存储的学生记录信息写入数据文件中;二是实现将单链表中存储的学生成绩和基本信息在屏幕界面上输出来。

3.2.1 模块功能的设计

? 主函数模块

用函数void main()来实现。主要是来显示主菜单,让用户选择操作。首先进行的是打开文件的操作,只有打开文件或创建文件成功,才能进入主菜单。之后应用了while(1)永真循环和switch-case语句来进行选择,是个比较简单实现的模块。最后若选择“0”则是退出永真循环。退出此系统之前如若未进行更新数据之后的保存操作,则会提示用户是否进行更新数据后的保存,然后才退出系统。 ? 录入学生记录模块

用函数void Type_in(Link l);来实现。主要功能用来对学生的成绩进行收集和输入。函数首先进行的是对读取的数据文件的数据收集工作,如若在指定路径找不到数据文件,系统则会创建新的数据文件;如果找到数据文件,系统则根据指定的文件读取方式度数据文件中的数据进行读取,并打印显示在界面上。之后会有个提示“输入新的学号(按数字0返回主菜单)”,这样就可以按照系统的提示输入学生的成绩信息了。录入学生记录模块可以录入学生的成绩信息,比如学号,姓名,成绩等。系统首先会根据用户输入的学号来用函数void stringinput(char *t,size_tlens,char *notice);对链表结点进行一一比对,以此来判定录入学生信息期间是否有重复学号输入,系统还会根据intnumberinput(char *notice);来判定学生的各科成绩录入是否在0到100之间。之后系统对学生的成绩进行总分汇总,并计算录入的每位学生的平均分。在本操作中,允许有重复的学生姓名出现。在此模块中,用到了一个控制变量flag,它是用来判定的条件变量,flag=1表示找到了与之重复的学号,系统会提示改学号已经被占用,是否重新输入?(y/n)flag=0表示未出现重复学号。系统默认按学号排序保存到文件中去(名次初始化为0)。录入数据完毕后按数字0即可返回主菜单。主要代码如下:

5 / 25

voidType_in(Link l) {

Node *p,*r,*s; r=l; s=l->next; system(\

printf(\欢迎进入增加学生记录界面\show(l); {

while(1) {

stringinput(num,10,\输入新的学号(按数字0返回主菜单):\格式flag=0;

/*该标志用于对输入字符串的合法性进行校验*/ /*若输入学号为0,则退出添加记录操作*/

/*先打印出已有的学生信息*/

/*将指针移至于链表最末尾,准备添加记录*/ while(r->next!=NULL)

r=r->next;

/*实现添加操作的临时的结构体指针变量*/

charch,flag=0,num[10];

while(1)/*一次可输入多条记录,直至输入学号为0的记录结点添加操作结束*/ 化输入学号并检验*/

if(strcmp(num,\输入为0,返回主界面*/

return; s=l->next; /*s指针指向头结点的后继结点,用于校验学号是否重复*/ while(s)/*查询该学号是否已经存在,若存在则要求重新输入学号*/

{ }

if(flag==1) {

/*提示用户是否重新输入*/

if(strcmp(s->data.num,num)==0) { }

s=s->next;

flag=1; break;

getchar();

printf(\该学号 %s 已经被占用,是否重新输入?(y/n):\scanf(\

if(ch=='y'||ch=='Y')

6 / 25

}

}

continue; return;

else

else

{break;}

/*申请内存空间*/

p=(Node *)malloc(sizeof(Node)); if(!p) {

printf(\申请空间失败! \/*如没有申请到,打印提示信息*/ }

stringinput(p->data.name,15,\姓名:\p->data.cgrade=numberinput(\语言成绩[0-100]:\ p->data.mgrade=numberinput(\高数成绩[0-100]:\ p->data.egrade=numberinput(\英语成绩[0-100]:\

/*输入并检验分

/*输入并检/*输入并检

return ;

/*返回主界面*/ strcpy(p->data.num,num); /*将字符串num拷贝到p->data.num中*/

数,分数必须在0-100之间*/ 验分数,分数必须在0-100之间*/ 验分数,分数必须在0-100之间*/ p->data.total=p->data.egrade+p->data.cgrade+p->data.mgrade;/*计算总分

p->data.ave=(float)(p->data.total/3);/*计算平均分,强制类型转换*/ p->data.mingci=0; }

} return ;

r->next=p; r=p; saveflag=1; /*增加的学生信息记录,名次初始化为零。*/

/*表明这是链表的尾部结点*/

/*将新建的结点加入链表尾部中*/

p->next=NULL; 7 / 25

? 按学号或姓名删除学生记录

用函数void Delete(Link l)来实现。主要功能是用来删除学生记录。首先有个链表判空的操作,如果链表不为空则显示删除前的信息记录。之后会有格式化输入字符串的判断,按照数字选择利用Node* Locate(Link l,charfindmess[],char nameornum[]);匹配学号或是姓名,之后利用if(p)/*p!=NULL*/语句,对链表中字段相匹配的结点进行删除操作,并释放其空间。删除成功后打印删除后的全体学生信息记录。具体代码如下: void Delete(Link l) {

int select; Node *p,*r;

charfindmess[20]; if(!l->next) {

system(\

printf(\链表为空,没有信息记录!无法删除!按回车键返回...\\n\ getchar(); getchar(); return; }

system(\

printf(\欢迎进入删除学生记录界面\ show(l);

printf(\选择1 按学号删除 =====>选择2 按姓名删除\\n\ printf(\请选择1或2:\ scanf(\ if(select==1) {

stringinput(findmess,10,\请输入您要删除的学生记录的学号:\ p=Locate(l,findmess,\ if(p) /*p!=NULL*/ { r=l; while(r->next!=p) r=r->next; r->next=p->next; /*将p所指节点从链表中去除*/ free(p); /*释放内存空间*/ printf(\删除成功!\\n\ show(l); saveflag=1; } else

Nofind(); getchar(); }

8 / 25

else if(select==2) /*先按姓名查询到该记录所在的结点*/ {

stringinput(findmess,15,\请输入您要删除的记录的学生姓名:\ p=Locate(l,findmess,\ if(p) {

r=l;

while(r->next!=p) r=r->next;

r->next=p->next; free(p);

printf(\删除成功!\\n\ show(l); saveflag=1; } else

Nofind(); getchar(); } else

Wrong(); getchar(); }

? 按学号或姓名来查询学生记录模块

用函数void Query(Link l);来实现。主要功能时用来查询学生记录。首先会有提示是按学号查询还是按姓名查询,再用if判断语句if(select==?)来进行查找,若找到则显示该学生的成绩信息记录并按回车键返回主菜单;如果没有找到与输入信息匹配的记录则显示“没有找到该学生的信息记录”。代码如下:

void Query(Link l) /*按学号或姓名,查询学生记录*/ {

int select;/*1:按学号查询,2:按姓名查询,其他:返回主界面(菜单)*/ char searchinput[20]; /*保存用户输入的查询内容*/ Node *p; if(!l->next) /*若链表为空*/ {

system(\

printf(\链表为空,没有学生的信息记录!无法查询!按回车键返回...\\n\

getchar(); getchar(); return; }

system(\

printf(\欢迎进入查询学生记录界面\\n\

9 / 25

printf(\按学号查询 =====>2 按姓名查询\\n\ printf(\请选择1或2:\ scanf(\

if(select==1) /*按学号查询*/ {

stringinput(searchinput,10,\请输入您所要查询的学号:\

p=Locate(l,searchinput,\ /*在链表中查找学号为searchinput值的结点,并返回结点的指针*/

if(p) /*若p!=NULL*/ {

printheader(); printdata(p); printf(END);

printf(\按回车键返回...\ getchar(); } else

Nofind(); getchar(); }

else if(select==2) /*按姓名查询*/ {

stringinput(searchinput,15,\请输入您所要查询的学生姓名:\ p=Locate(l,searchinput,\ if(p) {

printheader(); printdata(p); printf(END); printf(\按回车键返回...\ getchar(); } else Nofind(); getchar(); } else

Wrong(); getchar();

}

10 / 25

? 修改学生记录模块

用函数void Modify(Link l);来实现。主要功能是用来修改学生记录。首先是提示用户看看要修改的学生学号是否存在,这个是通过Node* Locate(Link l,charfindmess[],char nameornum[]);来判断的(学号是不会有重复的),如果学号存在,则系统会提示修改学号之外的值。最后将修改过后的记录打印出来,并提示修改成功!具体代码如下:

void Modify(Link l) {

Node *p;

charfindmess[20]; if(!l->next)

{ system(\

printf(\链表为空,没有信息记录!无法修改!按回车键返回...\\n\ getchar(); getchar(); return; }

system(\

printf(\欢迎进入修改学生记录界面\ show(l);

stringinput(findmess,10,\请输入您要修改的学生学号:\ /*输入并检验该学号*/

p=Locate(l,findmess,\ /*查询到该节点*/ if(p) /*若p!=NULL,表明已经找到该节点*/ { printf(\学号:%s,\\n\ printf(\姓名:%s,\ stringinput(p->data.name,15,\请输入新的名字:\ printf(\成绩:%d,\ p->data.cgrade=numberinput(\请输入新的C++成绩[0-100]:\ printf(\高数成绩:%d,\ p->data.mgrade=numberinput(\请输入新的高数成绩[0-100]:\ printf(\英语成绩:%d,\

p->data.egrade=numberinput(\请输入新的英语成绩[0-100]:\ p->data.total=p->data.egrade+p->data.cgrade+p->data.mgrade; p->data.ave=(float)(p->data.total/3); p->data.mingci=0;

printf(\修改成功!\\n\ show(l); saveflag=1; } else

Nofind(); getchar();

}

11 / 25

? 插入学生记录模块

用函数void Insert(Link l);来实现。主要功能是用来增加学生信息记录,若显示时没有此学生的信息,则不能进行该功能的操作。因为此模块算法采用的是后插法,首先是进行对插入结点位置的定位,然后在该结点后插入新的结点。如果可以进行插入操作,系统会先检查定位的结点是否存在(比对学号),然后再检查需要插入的新信息中学号是否重复,如果重复,系统会打印该学号的学生成绩信息,然后退出返回主菜单,本模块功能到此结束。主要代码如下:

void Insert(Link l) {

Link p,v,newinfo;

/*p指向插入位置,newinfo指新插入记录*/ /*s[]保存插入点位置之前的学号,num[]保存输

char ch,num[10],s[10]; int flag=0; v=l->next; system(\

printf(\欢迎进入插入学生记录界面\show(l);

if(l->next==NULL) { } while(1) {

flag=0; v=l->next; while(v) {

if(strcmp(v->data.num,s)==0) { }

12 / 25

入的新记录的学号*/

printf(\链表为空,没有学生的信息记录!无法进行后插操作!按回车getchar(); return ; 键返回...\\n\

stringinput(s,10,\请您输入学号,则插入的学生信息在该学号的后面:\

/*查询该学号是否存在,flag=1表示该学号存在*/

flag=1; break;

v=v->next;

}

if(flag==1) break; /*若学号存在,则进行插入之前的新记录的输入操作*/ else

{ getchar();

printf(\学号%s不存在!是否重新输入?(y/n):\ scanf(\ if(ch=='y'||ch=='Y') continue; else

return; }

}

/*以下新记录的输入操作与Type_in()相同*/ stringinput(num,10,\输入学号:\ v=l->next; while(v) { if(strcmp(v->data.num,num)==0) { printf(\对不起,学号'%s'已经存在!\\n\ printheader(); printdata(v); printf(END); printf(\ getchar(); getchar(); return;

}

v=v->next;

}

newinfo=(Node *)malloc(sizeof(Node));

if(!newinfo)

13 / 25

}

{ }

strcpy(newinfo->data.num,num);

stringinput(newinfo->data.name,15,\输入姓名:\newinfo->data.cgrade=numberinput(\成绩[0-100]:\newinfo->data.mgrade=numberinput(\高数成绩[0-100]:\newinfo->data.egrade=numberinput(\英语成绩[0-100]:\newinfo->data.total=newinfo->data.egrade+newinfo->data.cgrade+newinfo-newinfo->data.ave=(float)(newinfo->data.total/3); newinfo->data.mingci=0; newinfo->next=NULL;

saveflag=1; /*在main()有对该全局变量的判断,若为1,进行存盘*/ /******************************* 将指针赋值给p,因为l中的头节点的 下一个结点才实际保存着学生的记录。 *********************************/ p=l->next; while(1) {

if(strcmp(p->data.num,s)==0) /*在链表中插入一个结点*/ { } p=p->next;

newinfo->next=p->next; p->next=newinfo; break; printf(\申请失败!\/*如没有申请到,打印提示信息*/ return ;

/*返回主界面*/

>data.mgrade;

}

show(l); printf(\getchar();

14 / 25

? 统计学生总人数及各科目不及格人数模块

用函数void Statistics(Link l);来实现。主要功能是统计学生总人数和各科目不及格人数,以及指出各科的最高分学生的姓名。代码比较容易实现。 void Statistics(Link l)

{ Node *pm,*pe,*pc,*pt; /*用于指向分数最高的节点*/ Node *r=l->next;

intcountc=0,countm=0,counte=0; /*保存三门成绩中不及格的人数*/ if(!r)

{ system(\

printf(\链表为空,没有信息记录!无法统计!按回车键返回...\\n\ getchar(); getchar(); return ;} system(\

printf(\欢迎进入统计学生记录界面\ show(l);

pm=pe=pc=pt=r; while(r)

{ if(r->data.cgrade<60) countc++;

if(r->data.mgrade<60) countm++;

if(r->data.egrade<60) counte++;

if(r->data.cgrade>=pc->data.cgrade) pc=r; if(r->data.mgrade>=pm->data.mgrade) pm=r; if(r->data.egrade>=pe->data.egrade) pe=r; if(r->data.total>=pt->data.total) pt=r; r=r->next;} printf(\统计结果如下---------\\n\ printf(\分: %d 人\\n\ printf(\高数 <60分: %d 人\\n\ printf(\英语 <60分: %d 人\\n\

printf(\学 生 信 息 表 中 总 分 最 高 的人是: %s 最高总分是: %d\\n\

printf(\学 生 信 息 表 中 英语成绩最高的人是: %s 最高英语成绩是: %d\\n\

printf(\学 生 信 息 表 中 高数成绩最高的人是: %s 最高高数成绩是: %d\\n\

printf(\学 生 信 息 表 中 C++ 成绩最高的人是: %s 最高C++成绩是: %d\\n\ printf(\按回车键返回...\ getchar();

}

15 / 25

? 按总分成绩(插入排序法)降序排序模块

用函数void Sort(Link l);来实现。主要功能是用来对学生的记录按总分成绩进行降序排序。这样方便对学生总体成绩有个大致的了解。首先定义三个临时指针,为排序做基础。其中rr链表则是用于存储插入单个结点后保持排序的链表,ll始终为这个链表的头指针,每次都经过头指针寻找插入位置,此时rr作为移动指针按条件遍历链表;s为新建结点,用于保存从原链表中取出的结点信息,其指针域始终为空。找到正确位置后就是结点的插入操作而已了。 void Sort(Link l) {

Link ll;

Node *p,*rr,*s; inti=0;

if(l->next==NULL) {

system(\

printf(\链表为空,没有信息记录!无法排序!按回车键返回...\\n\ getchar(); getchar(); return ; }

ll=(Node*)malloc(sizeof(Node)); /*用于创建新的节点*/ if(!ll) {

printf(\申请空间失败!\ /*如没有申请到,打印提示信息*/ return ; /*返回主界面*/ }

ll->next=NULL; system(\ printf(\欢迎进入学生总分排名界面\\n\ printf(\名次排序前的学生信息表:\

show(l); /*显示排序前的所有学生记录*/ p=l->next; while(p) /*p!=NULL*/ {

s=(Node*)malloc(sizeof(Node)); /*新建结点用于保存从原链表中取出的结点信息*/ if(!s) {

printf(\申请空间失败!\/*如没有申请到,打印提示信息*/ return ; /*返回菜单界面*/ }

s->data=p->data; /*填数据域*/ s->next=NULL; /*指针域为空*/ rr=ll;

16 / 25

/*指针移至总分比p所指的结点的总分小的节点位置*/

while(rr->next!=NULL &&rr->next->data.total>=p->data.total) rr=rr->next;

if(rr->next==NULL)/*若新链表ll中的所有结点的总分值都比p->data.total大时,就将p所指结点加入链表尾部*/ rr->next=s;

else /*否则将该结点插入至第一个总分字段比它小的结点的前面*/ {

s->next=rr->next; rr->next=s; }

p=p->next; /*原链表中的指针下移一个结点*/ }

l->next=ll->next; /*ll中存储是的已排序的链表的头指针*/ p=l->next; /*已排好序的头指针赋给p,准备填写名次*/ while(p!=NULL) /*当p不为空时,进行下列操作*/ {

i++; /*结点序号*/ p->data.mingci=i; /*将名次赋值*/ p=p->next; /*指针后移*/ }

printf(\名次排序后的学生信息表:\ show(l); saveflag=1;

printf(\学生记录按总分降序排名完成!!!\\n\ getchar();

}

? 保存学生记录模块 用函数void Save(Link l);来实现。主要功能是用来对更新后的学生记录进行保存,并将其写进相应的数据文件中。函数首先进行文件的打开工作,检查当前文件的打开正常与否。如果打开失败则提示信息并返回主菜单,否则系统会将链表中的数据写入到磁盘文件中的数据文件中。如果用户对数据进行了更新但是没有使用该功能,则系统将会在用户想退出系统时提示用户是否进行保存。 void Save(Link l) {

FILE* fp; Node *p;

int count=0; if(!l->next) {

system(\

printf(\链表为空,没有信息记录!按回车键返回...\\n\ getchar(); getchar();

17 / 25

return; }

fp=fopen(\ /*以只写方式打开文件*/ if(fp==NULL) /*打开文件失败*/ {

printf(\打开文件发生错误!按回车键返回...\\n\ getchar(); return ; }

p=l->next; while(p) {

if(fwrite(p,sizeof(Node),1,fp)==1) /*每次写一个结点的信息至文件*/ {

p=p->next; count++; } else

break; }

if(count>0) {

getchar();

printf(\保存文件成功!保存的记录一共有:%d条\\n\ getchar(); saveflag=0; } else {

system(\ printf(\空表!!!没有学生信息记录需要保存!\\n\ getchar(); } fclose(fp); /*关闭此文件*/ }

18 / 25

? 显示学生记录模块

用函数void show(Link l);来实现。主要功能是用来显示学生的信息进行输出。在系统已经录入了学生记录的前提下,使用该功能可以显示学生的信息资料等等。同时按提示可跳出主菜单进行后续操作。主要的程序代码就是从链表表头开始询查,把每个结点包含的信息输出到界面,显示出来即可。

3.3 数据结构设计 3.3.1 学生成绩信息结构体

/*定义与学生有关的数据结构*/

struct student /*标记为student*/ {

char num[10]; /*学号*/ char name[15]; /*姓名*/ intcgrade; /*C语言成绩*/ intmgrade; /*数学成绩*/ integrade; /*英语成绩*/ int total; /*总分*/ float ave; /*平均分*/ intmingci; /*名次*/ };

结构体将用于存储学生的基本信息,它将作为单链表的数据域。

3.3.2 单链表node结构体 typedefstruct node {

struct student data;

struct node *next;

/*数据域*/

/*指针域*/

}Node,*Link; /*Node为node类型的结构变量,*Link为node

类型的指针变量*/

这样定义了一个单链表的结构,结构标记为node,data为结构体类型的数据,作为单链表结构中的数据域,next为单链表中的指针域,用来存储其直接后继节点的地址。Node为node类型的结构变量,*Link为node类型的指针变量。

19 / 25

4 测试结果

当用户运行程序进入系统时,其主界面如下图所示。用户可选择0~9之间的数值,调用相应功能进行操作。当输入为0时,退出此管理系统。

当用户输入1并按Enter键后,即可进入数据录入界面,其输入过程如图所示,当用户输入为0的学号时,它会结束输入过程,显示主菜单。

20 / 25

当用户输入2并按Enter键后,即可进入记录删除界面,然后在选择1或2进行按学号或姓名进行记录删除,再输入要删除的学号或姓名,这里按学号删除了一条学号为03的记录,如下图所示:

当用户输入3并按Enter键后,即可进入记录查询界面,然后再选择1或2进行按学号或姓名进行记录查询,再输入要查询的学号或姓名,这里按学号查询了一条学号为05的记录,如下图所示:

21 / 25

当用户输入4并按Enter键后,即可进入记录修改界面,系统提示按学号修改学生信息。这里是修改了学号为01的一个学生的成绩信息。如下图所示:

当用户输入0时,若系统没保存更新,则提示是否保存,输入y后按Enter键即可保存改动,如下图所示;若已经保存更新则直接提示已经退出系统,按任意键即可关闭运行界面。

其他的界面功能操作见模块功能设计,就不一一展示了。

22 / 25

5 结论

通过上学期对数据结构这门课的学习,我了解到:“数据结构与算法”是计算及机科学的基础课程,数据结构的研究不仅涉及到计算机硬件,而且和计算机软件的研究有着更密切的关系,无论是编译程序还是操作系统,都涉及到数据元素在存储器中的分配问题。在研究信息检索时也必须考虑如何组织数据,以便使查找和存取数据元素更为方便。可以认为数据结构是介于数学、计算机硬件和计算机软件三者之间的一个核心内容,是从事计算机科学研究及其应用的科技工作者必须掌握的重要内容。

这次的课程设计有效的培养了我们独立思考的能力,提高了我们的动手操作水平。在具体设计操作中,我们巩固了上学期所学的数据结构与算法的理论知识,进一步提高了自己的编程能力。这也是课程设计的最终目的所在。通过实际操作,开发了自己的逻辑思维能力,培养了分析问题、解决问题的能力。

在这次课程设计中我也知道了自己的动手能力不强,有待于进一步提高。在设计过程中很难把书本上的知识与实际相结合,在调试过程中一次次出错,差点自我放弃,但在老师和同学的帮助下,我坚持到了最后。我在这次课程设计中学到很多,我会更加自信的走下去。

在课程设计中我体会到:一个好的程序应该是一个所占空间小、运行时间短、其他性能也好的程序。而要做出一个好的程序则应该通过对算法与其数据结构的时间复杂度和空间复杂度进行实现与改进。然而,实际上很难做到十全十美,原因是各要求有时相互抵触,要节约算法的执行时间往往要以牺牲更多的存储空间为代价:而为了节省存储空间又可能要以更多的时间为代价。因此,只能根据具体情况有所侧重:如果程序的使用次数较少,则应该力求算法简明易懂,而易于转换为上机程序;如果程序反复多次使用,则应该尽可能选用快速算法;如果解决问题的数据量极大,机器的内存空间较小,则在编写算法时应该考虑如何节省空间。 学习了《数据结构与算法》这门课,我们在编写程序时就应该注意到所编写程序的时间复杂度和空间复杂度,以及是否运用了良好的算法,而不是只是象以前编写程序时单纯使用c的知识。我们要充分考虑程序的性能,争取编写出更好的程序。

总之,通过这次课程设计我认识到了自己的许多不足之处,在今后的学习生活中,一定要勤于思考,扎实掌握理论知识,灵活运用课上所学。

23 / 25

参考文献

[1]罗建军,朱丹军,顾刚等编著,C++程序设计教程(第2版),北京:高等教育出版社,2010.7

[2]张玲玲编著,C语言编程新手自学手册,北京:机械工业出版社,2012.1 [3]谭浩强编著,C++程序设计,北京:清华大学出版社,2008.10 [4]李鹏程编著,C++宝典,北京:电子工业出版社,2010.5

[5]刘锐宁,梁水,李伟名编著,Visual C++开发实战1200例,北京:清华大学出版社,2011.1

[6]钱丽萍编著,C++数据结构与程序设计,北京:清华大学出版社,2004.11 [7]严蔚敏,吴伟民编著,数据结构(C语言版),北京:清华大学出版社,2006.5

24 / 25

本文来源:https://www.bwwdw.com/article/uft7.html

Top