学生成绩管理数据结构课程设计报告.docx
《学生成绩管理数据结构课程设计报告.docx》由会员分享,可在线阅读,更多相关《学生成绩管理数据结构课程设计报告.docx(40页珍藏版)》请在冰点文库上搜索。
学生成绩管理数据结构课程设计报告
学生成绩管理系统
数据结构课程设计
一、课程设计的内容与目的
利用所学数据结构理论知识完成“学生成绩管理系统”的设计。
通过课程设计提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。
具体包括:
了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;
初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;
提高综合运用所学的理论知识和方法独立分析和解决问题的能力;
训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。
二、课程设计的要求与数据
1.系统功能需求分析:
1、输入功能:
可以输入40位同学信息
2、增加功能,能增加学生的信息
3、浏览功能:
完成对全部学生记录浏览
4、查询功能:
采用散列查找完成按学号查找学生记录
5、排序功能:
采用直接选择排序,将学生平均成绩从低到高排序输出
6、删除功能:
可以删除学生信息
7、修改功能:
可以对学生信息的各项信息进行修改
8、插入功能:
完成数据的插入
9、统计功能:
统计出各分数段学生人数(60分以下,60~70,71~80,...)
2.存储结构设计分析:
3.学生的信息:
学生的信息采用结构体类型定义,每个元素表示一个学生的信息,包括学号,姓名及数据结构平均成绩4个数据项:
(1)structstudent
{charnum[11];
charname[20];
intscore[8];
floatave;
}stu[N];
(2)散列表的结点类型定义:
typedefstructnode{unsignedlongintkey;
structnode*link;}HNode;
3.源程序如下:
#include
#include
#include
/*控制学生记录的容量*/
#defineN40
#definePRprintf("\n\r%s%s%s%s%s%s%s%s%s%s%s",stu[i].num,stu[i].name,stu[i].score[0],stu[i].score[1],stu[i].score[2],stu[i].score[3],stu[i].score[4],stu[i].score[5],stu[i].score[6],stu[i].score[7],stu[i].score[8],stu[i].ave)
structstudent
{charnum[11];
charname[20];
intscore[8];
floatave;
}stu[N];
typedefstructnode{unsignedlongintkey;
structnode*link;}HNode;
typedefstruct{intkey;/*排序码*/
floatdata;/*其他数据项*/}RecNode;
/*全新保存函数*/
save(intn)/*保存函数,保存n个记录*/
{FILE*fp;
inti;
if((fp=fopen("sc.txt","wb"))==NULL)/*以输出打开方式,在此前的记录被覆盖*/
{printf("\n不能打开文件\n");
getch();returnNULL;
}
for(i=0;iif(stu[i].ave!
=0)/*stu[i].ave=0表此记录已删除*/
if(fwrite(&stu[i],sizeof(structstudent),1,fp)!
=1)
printf("文件输入错误\n");
fclose(fp);
}
/*加载记录或可以计算记录个数的函数*/
load()/*加载记录或可以计算记录个数的函数*/
{FILE*fp;
inti;
if((fp=fopen("sc.txt","rb"))==NULL)/*以输出打开方式,在此前的记录被覆盖*/
{printf("\n不能打开文件\n");
getch();returnNULL;
}
for(i=0;!
feof(fp);i++)
fread(&stu[i],sizeof(structstudent),1,fp);
fclose(fp);
return(i-1);/*返回记录个数*/
}
/*一个任务结束时的选择浏览还是返回的函数*/
voidprintf_back()/*一个任务结束时的选择浏览还是返回*/
{intk,w;
printf("\n\n\t^-^★成功★^-^\n\n");
printf("请选择:
\n\n\t1).现在浏览全部\t2).返回:
[]\b\b");
scanf("%d",&w);
if(w==1)browse();
elseteacher();
}
/*显示数据结构项目函数*/
voidprintf_face()/*显示数据结构项目*/
{printf("\n\t学号姓名\t英语数学C语言管理学信检体育近代史线数平均分\t\n");
}
average(inti)/*对第i个记录的分数求平均值*/
{intj,sum;
for(sum=0,j=0;j<8;j++)
sum+=stu[i].score[j];
stu[i].ave=sum/8.0;
}
/*学号输入函数*/
no_input(inti,intn)/*i表示第i个的学生信息,n表示比较到第n个学生*/
{intj,k,w1;
do
{w1=0;
printf("学号:
");
scanf("%s",stu[i].num);
for(j=0;stu[i].num[j]!
='\0';j++)/*学号输入函数,作了严格规定*/
if(stu[i].num[j]<'0'||stu[i].num[j]>'9')/*判断学号是否为数字*/
{puts("Inputerror!
Onlybemadeupof(0-9).Pleasereinput!
\n");
w1=1;break;
}
if(w1!
=1)
for(k=0;k/*排除第i个学生记录即你要修改的*/
if(k!
=i&&strcmp(stu[k].num,stu[i].num)==0)/*判断学号是否有雷同*/
{puts("该记录已存在.请重新输入!
\n");
w1=1;break;
}
}
while(w1==1);
}
/*对分数输入*/
score_input(inti)
{intj;printf("1.英语2.数学3.C语言4.管理学5.信检6.体育7.近代史8.线性代数\n");
for(j=0;j<8;j++)
{printf("score%d:
",j+1);
scanf("%d",&stu[i].score[j]);
}
}
/*输入一个记录函数*/
input(inti)/*输入一个记录函数*/
{
no_input(i,i);/*调用学号输入函数*/
printf("姓名:
");
scanf("%s",stu[i].name);
score_input(i);/*调用分数输入函数*/
average(i);/*调用求平均值函数*/
}
/*显示一个记录的函数*/
printf_one(inti)/*显示一个记录的函数*/
{intj;
printf("%11s%-10s",stu[i].num,stu[i].name);
for(j=0;j<8;j++)
printf("%-6d",stu[i].score[j]);
printf("%-7.2f\n",stu[i].ave);
}
voidputs___()/*显出---函数*/
{puts("\n--------------------------------------------------------------------");
}
/*修改记录函数*/
modify_data(inti,intn)/*修改数据函数,修改第i个记录*/
{intc,w1;
do/*输入选择作个判断*/
{puts("\nmodifyby=>\n\n1).学号2.姓名3).英语4).数学\n5).C语言6).管理学7).信检8).体育9).近代史\n10).线性代数11).allscore12).alldata13).cancelandback");
printf("请选择:
[]\b\b");
scanf("%d",&c);
if(c>13||c<1)
{puts("\n选择错误!
重新选择!
");/*判断选择是否错误,若是则重新选择性*/
getchar();/*当输入是字符时可以防止死循环*/
}
}
while(c>13||c<1);
do
{switch(c)/*选择要修改的项目*/
{case1:
no_input(i,n);break;/*调用学号输入函数*/
case2:
printf("姓名:
");scanf("%s",stu[i].name);break;
case3:
printf("英语:
");scanf("%d",&stu[i].score[0]);break;
case4:
printf("数学:
");scanf("%d",&stu[i].score[1]);break;
case5:
printf("C语言:
");scanf("%d",&stu[i].score[2]);break;
case6:
printf("管理学:
");scanf("%d",&stu[i].score[3]);break;
case7:
printf(":
信检");scanf("%d",&stu[i].score[4]);break;
case8:
printf("体育:
");scanf("%d",&stu[i].score[5]);break;
case9:
printf("近代史:
");scanf("%d",&stu[i].score[6]);break;
case10:
printf("线性代数:
");scanf("%d",&stu[i].score[7]);break;
case11:
score_input(i);break;/*调用分数输入函数*/
case12:
input(i);break;/*调用输入整条学生记录*/
case13:
teacher();/*直接返回教师介面*/
}
if(c>2&&c<10)
average(i);/*调用求平均值函数*/
puts("\nNow:
\n");
printf_face();/*调用显示数据结构项目函数*/
printf_one(i);/*修改后的记录让用户确认*/
printf("\n是否确定?
\n\n\t1).确定2).重新修改3).不保存返回[]\b\b");/*是否确定*/
scanf("%d",&w1);/*选择2则表示这次修改错误要重新修改*/
}
while(w1==2);
return(w1);/*返回控制值*/
}
/****************输入模块****************/
enter()/*输入模块*/
{inti,n;
printf("输入学生总数(0-%d)?
:
",N);
scanf("%d",&n);/*要输入的记录个数*/
printf("\n现在输入数据\n\n");
for(i=0;i{printf("\nInput%dthstudentrecord.\n",i+1);
input(i);/*调用输入函数*/
}
if(i!
=0)save(n);/*调用保存函数*/
printf_back();/*一个任务结束时让用户选择是浏览还是返回*/
}
/****************追加模块****************/
add()/*追加模块*/
{inti,n,m,k;
FILE*fp;
n=load();
printf("增加的学生总数(0-%d)?
:
",N-n);
scanf("%d",&m);/*输入要追加的记录个数*/
k=m+n;
for(i=n;i{printf("\nInput%dthstudentrecord.\n",i-n+1);
input(i);/*调用输入函数*/
}
if((fp=fopen("sc.txt","ab"))==NULL)/*以ab方式打开文件,追加保存*/
{printf("不能打开文件\n");
return;
}
for(i=n;iif(fwrite(&stu[i],sizeof(structstudent),1,fp)!
=1)
printf("文件输入错误\n");
fclose(fp);
printf_back();/*一个任务结束时的选择浏览还是返回*/
}
/****************修改模块****************/
modify()/*修改模块*/
{structstudents;
FILE*fp;
inti,n,k,w0=1,w1,w2=0;
n=load();
do
{system("cls");
k=-1;
/*给用户看全部记录以便确认要修改的记录*/
puts___();/*显示-----*/
printf_face();/*调用显示数据结构项目函数*/
for(i=0;i{if((i!
=0)&&(i%10==0))/*目的是分屏显示*/
{printf("\n\nRememberNO.whichneededmodify.passanykeytocontiune...");
getch();
puts("\n\n");
}
printf_one(i);/*调用显示一个记录的函数*/
}
puts___();
do
{printf("\n\n输入修改学号!
NO.:
");
scanf("%s",s.num);/*输入要修改的数据的学号*/
for(i=0;iif(strcmp(s.num,stu[i].num)==0)
{k=i;/*找到要修改的记录*/
s=stu[i];/*把stu[i](即当次修改的学生记录)备份给s,以便用户反悔时恢复名誉*/
}
if(k==-1)printf("\n\n不存在!
重新输入");
}
while(k==-1);/*当K=-1表示没有找到*/
printf_face();/*调用显示数据结构项目函数*/
printf_one(k);/*调用显示一个记录的函数*/
w1=modify_data(k,n);/*修改学生记录并且返回保存控制值w1,w1=1则表示用户已确认修改*/
if(w1==1)/*W1等于1时则表示用户确定这次修改*/
{printf("\n^-^★成功★^-^.\n\n是否修改其他?
\n\n\t1).是2).保存返回\t[]\b\b");
scanf("%d",&w0);
w2=1;/*来控制保存,使w2=1是标记已有过修改*/
}
else
{w0=0;
if(w2==1)
stu[k]=s;
}/*走到这里是由于用户没有确认这次修改(在调用修改函数w1=modify_data(k,n);时没有确认).使W0=0,为了让终止循环,
stu[k]=s,则把备份的s恢复给stu[k](即当次修改的),这样的好处是确保在此之前修改过的成功保存,而本次(用户没有确认的)不修改*/
if(w0!
=1&&w2==1)/*W0不等于1则表示正常返回,w2=1表示在此之前有过修改,这时就保存用户已确认修改的并返回*/
save(n);/*w2不等于1表示在此次之前没有修改过(即:
第一次),而又反悔这次修改,则不保存返回*/
}
while(w0==1);
teacher();
}
/****************删除模块****************/
del()/*删除模块*/
{structstudents;
FILE*fp;
inti,j,n,k,c,w0=1;
n=load();
do
{system("cls");
k=-1;
/*给用户看全部记录以便确认要删除的记录*/
puts___();
printf_face();/*调用显示数据结构项目函数*/
for(i=0;iif(stu[i].ave!
=0)
{if((i!
=0)&&(i%10==0))/*目的是分屏显示,每10个一屏*/
{printf("\n\nRememberNO.whichneededdel.passanykeytocontiune...");
getch();
puts("\n\n");
}
printf_one(i);/*调用显示一个记录的函数*/
}
puts___();
do
{printf("\n\n输入删除学号!
NO.:
");
scanf("%s",s.num);/*输入要修改的数据的学号*/
for(i=0;iif(strcmp(s.num,stu[i].num)==0)
{k=i;/*找到要修改的记录的下标赋给K*/
s=stu[i];
}
if(k==-1)printf("\n\n不存在!
重新输入");/*K=-1,表示没有找到相同之的*/
}
while(k==-1);
puts("\n");
printf_face();/*调用显示数据结构项目函数*/
printf_one(k);/*调用显示一个记录的函数*/
printf("\n是否确定?
\n\t1).是2).否且删除其他3).保存全部返回[]\b\b");
scanf("%d",&c);
if(c==1)
{stu[k].ave=0;/*stu[k].ave=0用来标识这个记录是要删除的.保存时则不保存stu[k].ave=0的数据*/
printf("\n\n^-^★成功★^-^.\n\n是否重输?
\n\t1).是2).返回菜单\t[]\b\b");/*问是否继续*/
scanf("%d",&w0);
}
if(c==3)w0=0;/*w0=0不删除直接返回*/
if(w0!
=1&&c!
=3)/*只有当确认删除后返回才保存,不删除直接返回则不保存,且不保存在此之前删除过的记录*/
save(n);
}
while(w0==1);
teacher();/*返回教师介面*/
}
/****************浏览(全部)模块****************/
browse()/*浏览(全部)模块*/
{inti,j,n;
n=load();/*加载记录*/
system("cls");
puts___();
printf_face();/*调用显示数据结构项目函数*/
for(i=0;i{if((i!
=0)&&(i%10==0))/*目的是分屏显示*/
{printf("\n\nPassanykeytocontiune...");
getch();
puts("\n\n");
}
printf_one(i);/*调用显示一个记录的函数*/
}
puts___();
printf("\tThereare%drecord.\n",n);
printf("\nPassanykeytoback...");
getch();/*按任意健*/
teacher();
}
/****************查找模块****************/
inth(chark)
{return(k%5);}
intlinkinsert(HNode*t[],chark)
{/*向用拉链法处理冲突的散列表t中插入关键字为k的记录*/
inti;
HNode*p;
i=h(k);
if(t[i]==NULL)
{p=(HNode*)malloc(sizeof(HNode));
p->key=k;p->link=NULL;
t[i]=p;printf("\ninserted%lu\n",k);
return
(1);}
else
{p=t[i];
while(p!
=NULL)
if(p->key==k)
{printf("\nretrieval%lu\n",k);return(0);}
elseif(p->link!
=NULL)p=p->link;
else{p->link=(HNode*)malloc(sizeof(HNode));
p=p->link;p->key=k;p->link=NULL;
printf("\ninserted%lu\n",k);return
(1);
getch();
}
}
}
HNode*linksearch(HNode*t[],chark)
{/*在用拉链法处理冲突的散列表t中查找关键字为给定值k的记录*/
HNode*p;
inti;
i=h(k);
if(t[i]==NULL)return(NULL);
p=t[i];
while(p!
=NULL)
if(p->key==k)
{printf("%lu\n",p->key);
return(p);}
elsep=p->link;
return(NULL);
}
search()/*查找模块*/
{inti,n,k,w1=1,w2,w3,w4;
structstudents;
n=load();
do
{do
{k=-1;
printf("\n\n输入查找学号!
NO.:
");
scanf("%s",s.num);/*输入要修改的数据的学号*/
printf_face();/*调用显示数据结构项目函数*/
for(i=0;iif(st