学生成绩管理系统(线性表版)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学年论文
(数据结构 2015—2016 第一学期)
题目: 数据结构课程设计
作者:陈炳宏
所在学院:信息科学与工程学院
专业年级:信息安全14-1
指导教师:刘淑娴
职称:副教授
2016年 1 月 4 日
一.学生成绩管理系统 (1)
1。
1需求分析 (1)
1。
1.1程序分析: (1)
1。
1.2执行方式: (1)
1。
1.3 程序执行的命令包括: (1)
1.1.4测试数据: (2)
1.2概要设计 (2)
1.2.1 线性表的抽象数据类型定义为: (3)
1.2。
2 结点的抽象数据类型定义为: (3)
1。
2。
3指针的抽象数据类型定义为: (3)
1。
2.4本程序包含8个模块: (4)
1。
3详细设计 (5)
1.3.1 元素类型、结点类型和指针类型 (5)
1.3.2 函数说明 (5)
1。
3.3 功能函数 (5)
1。
4 调试分析 (15)
1.5 用户手册 (15)
1。
6测试结果 (18)
一.学生成绩管理系统
1.1需求分析
1.1。
1程序分析:
本程序是一个基于线性表结构编写的学生成绩管理系统,学生可以进行包括学生信息建立、在不同位置插入学生信息、查询指定学生信息、删除指定学生信息和输出显示所有学生信息这五项功能,功能操作简单,效率高,可延展性强. 为保证信息的真实性,学生信息中学号长度num<=11,姓名长度name〈=8,性别gender<=3,成绩仍意输入,并且学号和成绩只能为数字,否则程序出错。
1。
1。
2执行方式:
本程序以用户和计算机的对话方式执行,即在计算机终端上显示7个共能选择的“提示信息"之后,由用户在键盘上输入本程序中规定的功能指令;相应的输人数据(并能滤去输入中的非法字符)和显示信息来处理结果。
1.1.3 程序执行的命令包括:
(1)学生信息链表的建立;
建立后仍意建继续输入,n和N退出;
(2)插入学生信息;
输入插入的位置;
(3) 查询学生信息;
选择两种方式之一查找并查询;
(4)删除学生信息;
选择两种方式之一查找并删除;
(5)修改学生信息;
选择两种方式之一查找并修改;
(6) 输出所有学生信息;
(7)退出管理系统.
1.1.4测试数据:
(1)建立三个学生信息:
学号(11)姓名(8)性别成绩
20141305210,cc,n,89
20141302399,sxz,w,99
20151432596,sad,n,88
(2) 插入一个学生信息:
学号(11)姓名(8)性别成绩
2016,scs,n,79
输入插入位置:
2
(3) 查询学生信息:
按1选择学号查询,
输入学号:20141305210
按2选择姓名查询,
输入姓名:scz
(4) 删除学生信息:
按2选择姓名删除,
输入姓名:cc
(5)修改学生信息:
按1选择学号修改,
输入学号:20141302399
输入修改后的数据:
学号(11)姓名(8) 性别成绩
20141312399,scz,w,69
1。
2概要设计
为实现上述程序功能,首先需要创建一个建立信息链表的函数,用于建立线性链表并对每个结点进行顺序的信息存储,然后创建其他五个函数,来依次实现插入、删除、查询、修改、输出信息。
其中插入信息需要利用循环使得指针循环指向指定结点,而删除、查询和修改均需要利用循环判断来找到指定数据。
1.2.1 线性表的抽象数据类型定义为:
typedef struct {
数据对象:char num,name,genger,score;
数据关系:一对一的线性关系}DataType;
基本操作:建立一对一的信息组
1.2。
2 结点的抽象数据类型定义为:
typedef struct node{
数据对象:DataType data;
struct node *next;
数据关系:*next∈data;}ListNode;
基本操作:
ListNode *findList(LinkList head);
初始条件:链表指针类型的建立
操作结果:查询函数为指针类型
void changeNode(LinkList head);
初始条件:查询函数调度成功,选择处有数据
操作结果:新数据覆盖原数据来修改
void delNode(LinkList head);
初始条件:查询函数调度成功,选择处有数据
操作结果:选中数据被释放
void printList(LinkList head);
初始条件:线性表存在且其余操作完成
操作结果:输出显示最终数据
1.2。
3指针的抽象数据类型定义为:
typedef {
数据对象:ListNode *LinkList;
LinkList head;
数据关系:LinkList初始为head
基本操作:
LinkList createList(void)
初始条件:建立一对一的信息组
操作结果:建立信息链表函数
1.2.4本程序包含8个模块:
(1)主程序模块:
BEGIN{main}
初始化;
SWITCH
接受命令;
处理命令;
UNTIL 数据处理结束;
END。
(通过返回的菜单选择函数值进行功能选择并调用实现功能;)(2)菜单选择—-单纯的选择功能序号并返回给主函数;
(3)链表建立函数-—实现顺序链表的建立并输入相应的数据进行结点的存储;
(4) 插入信息函数——通过找到指定节点并进行结点插入的函数;
(5)查询信息函数——通过循环对输入的学号和姓名和已经存在数据一个一个往后对比来查找全部函数;
(6) 删除信息函数——通过查询函数的基本原理,找到指定函数后,释放指定结点;
(7) 修改信息函数-—通过查询函数的基本原理,找到指定函数后,修改并覆盖原结点;
(8) 输出所有信息函数--利用循环依次输出结点直到结点为空为止.
各模块之间的调用关系如图1:
图1 模块调用关系图
1。
3详细设计
1.3。
1 元素类型、结点类型和指针类型
TYPEDEF DataType—char,int;{元素类型}
LinkList—head;{指针类型}
ListNode—node;{结点类型}
data:DataType;
next:*node;
END;
ViSitProc—PROCEDURE(p:LinkType);
{访问结点的过程类型}
1.3。
2 函数说明
int menu_select();
LinkList createList(void);
void printList(LinkList head);
int insertNode(LinkList head,ListNode *p,int i);
ListNode *findList(LinkList head);
void delNode(LinkList head);
void changeNode(LinkList head);
1.3.3 功能函数
(1)建立链表函数
LinkList createList(void)
{
ListNode *p,*rear; //结点指针
char flag; //判断是否继续输入的标志
head=(ListNode *)malloc(sizeof(ListNode));//头节点指针开辟内存rear=head; //开始头与尾相同
while(flag!='n’&&flag!=’N’)
{
p=(ListNode *)malloc(sizeof(ListNode)); //结点指针开辟空间
printf(”\n学号(11)姓名(8) 性别成绩\n”);
scanf(”%s%s%s%d",p—>data.num,p->data。
name,p—〉data。
gender,&p —>data.score);
rear—〉next = p;//让尾结点指向当前结点的下一结点,并且该节点赋值为p 结点
rear = rear—>next; //尾结点指针指向下一结点
printf("按n或N退出,按其他键继续输入\n");
getchar();//对标志赋值判断是否继续
scanf(”%c”,&flag);
}
rear->next=NULL;//让尾结点的下一结点为空来结束链表
return head;//返回头指针
}
(2)插入信息函数
int insertNode(LinkList head,ListNode *p,int i)
{
ListNode *p1;
int j=1;
p1=head;
if(p1—>next==NULL)//判断如果为空表,则插入作为第一个结点*//
{
if(i==0)
{
p1->next=p;//让头节点的指向下一节点,且该结点为p结点
p-〉next=NULL; //p结点的下一结点为空来结束链表
}
else return -1; //如果在空表情况下输入大于0位置,则返回-1。
}
while((j<=i-1)&&(p1!=NULL))//找到第i—1个结点,p1指向该结点//
{ p1=p1-〉next; j++; }
if(p1==NULL)//如果仍然没有合适的插入点,则返回-1//
return —1;
p—>next=p1-〉next; //有就让p结点的下一位置指向当前结点的下一结点
p1-〉next=p;//并重新让当前结点指向的下一节点变为p结点
return 0;
}
(3)查询信息函数
ListNode *findList(LinkList head)
{
ListNode *p;
char num[12];
char name[9];
int xz;
printf("===========================\n”);
printf(”1、按学号查询\n");
printf("2、按姓名查询\n”);
printf("===========================\n”);
printf(”请选择: ");
p=head-〉next;//p为头节点的下一节点
scanf(”%d”,&xz);
if (xz==1)
{
printf(”请输入要查找学生的学号:");
scanf(”%s”,num);
while(p && strcmp(p—〉data。
num,num)!=0) //循环匹配输入信息是否与当前结点一致,若不一致就转入下一结点进行匹配
p=p-〉next;
}
else if (xz==2)
{
printf("请输入要查找学生的姓名:”);
TYPEDEF DataType—char,int;{元素类型}
LinkList—head;{指针类型}
ListNode—node;{结点类型}
data:DataType;
next:*node;
END;
ViSitProc—PROCEDURE(p:LinkType);
{访问结点的过程类型}
int menu_select();
LinkList createList(void);
void printList(LinkList head);
int insertNode(LinkList head,ListNode *p,int i);
ListNode *findList(LinkList head);
void delNode(LinkList head);
void changeNode(LinkList head);
LinkList createList(void)
{
ListNode *p,*rear; //结点指针
char flag; //判断是否继续输入的标志
head=(ListNode *)malloc(sizeof(ListNode));//头节点指针开辟内存
rear=head; //开始头与尾相同
while(flag!='n’&&flag!=’N’)
{
p=(ListNode *)malloc(sizeof(ListNode)); //结点指针开辟空间
printf("\n学号(11)姓名(8) 性别成绩\n");
scanf("%s%s%s%d”,p-〉data。
num,p—〉,p—〉data。
gender,&p-〉data。
score);
rear-〉next = p;//让尾结点指向当前结点的下一结点,并且该节点赋值为p结点
rear = rear-〉next; //尾结点指针指向下一结点
printf(”按n或N退出,按其他键继续输入\n");
getchar();//对标志赋值判断是否继续
scanf(”%c”,&flag);
}
rear—>next=NULL;//让尾结点的下一结点为空来结束链表
return head;//返回头指针
}
int insertNode(LinkList head,ListNode *p,int i)
{
ListNode *p1;
int j=1;
p1=head;
if(p1—〉next==NULL)//判断如果为空表,则插入作为第一个结点*//
{
if(i==0)
{
p1—>next=p;//让头节点的指向下一节点,且该结点为p结点
p-〉next=NULL; //p结点的下一结点为空来结束链表
}
else return —1; //如果在空表情况下输入大于0位置,则返回—1。
}
while((j<=i-1)&&(p1!=NULL))//找到第i—1个结点,p1指向该结点// { p1=p1-〉next; j++; }
if(p1==NULL)//如果仍然没有合适的插入点,则返回—1//
return -1;
p—〉next=p1—>next; //有就让p结点的下一位置指向当前结点的下一结点p1—>next=p;//并重新让当前结点指向的下一节点变为p结点
return 0;
}
ListNode *findList(LinkList head)
{
ListNode *p;
char num[12];
char name[9];
int xz;
printf(”===========================\n”);
printf(”1、按学号查询\n");
printf("2、按姓名查询\n”);
printf("===========================\n”);
printf(”请选择: ");
p=head->next;//p为头节点的下一节点
scanf(”%d”,&xz);
if (xz==1)
{
printf("请输入要查找学生的学号:");
scanf(”%s",num);
while(p && strcmp(p—〉data。
num,num)!=0) //循环匹配输入信息是否与当前结点一致,若不一致就转入下一结点进行匹配
p=p->next;
}
else if (xz==2)
{
printf(”请输入要查找学生的姓名:");
scanf("%s”,name);
while (p && strcmp(p—>,name)!=0) //同上匹配姓名
p=p->next;
}
return p;
}
(4)删除信息函数
void delNode(LinkList head)
{
ListNode *p,*q;
printf(”请先查找您要删除的学生信息:\n");
p=findList(head);//调用查找函数找到要查找的函数
if(p==NULL)//查找为空的情况
{
printf(”没有查到要删除的学生信息");
return;
}
q=head;
while(q!=NULL && q—〉next!=p)
q=q—>next; //让q指向到要删除的结点位置
q—〉next=p—>next; //让q的下一结点直接指向到删除结点的下一结点位置
free(p); //释放p结点内容
printf(”该学生信息已被删除!\n”);
}
(5)修改信息函数
void changeNode(LinkList head)
{
ListNode *p;
printf("请先查找您要修改的学生信息:\n”);
p=findList(head);
if(p==NULL)
{
printf(”没有查到要修改的学生信息");
}
else
{
printf("\n请输入修改后的数据\n");
printf(”\n学号(11) 姓名(8)性别成绩\n”);
printf(”—--—-——-——-———------—--————-——--—-———-—-———\n”);
scanf(”%s%s%s%d",p—>data。
num,p-〉,p—〉data.gender,&p—>data.score);
printf("修改成功!"); //找到要修改的结点地址后,对其中的内容进行重新输入来修改
printf(”——--——-—-————---——-------——-——-—————----——————-—————------—-——--——\n”);
}
}
(6) 主程序和菜单程序
主程序:
void main()
{
ListNode *p;
int i;
while(1)//无限循环保证功能持续进行,一直到人为选择结束
{
switch(menu_select())//通过菜单函数返回的值来进行功能选择
{
case 1:
printf("**************************************\n”);
printf(”学生信息链表的建立 \n”);
printf(”***************************************\n”);
head = createList();
break;
case 2:
printf("**************************************\n”);
printf(”添加学生信息\n”);
printf(”**************************************\n”);
printf(”\n学号(11)姓名(8)性别成绩\n");
printf(”**************************************\n”);
p=(ListNode *)malloc(sizeof(ListNode));
scanf("%s%s%s%d”,p-〉data.num,p—>data。
name,p->data。
gender,&p —〉data。
score);
printf("请输入要插入的位置:\n”);
fflush(stdin);
scanf(”%d”,&i);
if(insertNode(head,p,i)==-1)
{
printf("没有合适的插入点!\n”);
}
else
{
printf(”结点已经插入\n”);
}
break;
case 3:
printf(”**************************************\n”);
printf(”查询学生信息\n");
printf("**************************************\n");
p=findList(head);
if(p!=NULL)
{
printf("\n查询的学生信息如下\n");
printf(”\n学号(11)姓名(8)性别成绩\n”);
printf("-———-—-—-—--—--—--—-—-——-—--—---—--———-—--—\n”);
printf(”%s,%s,%s,%d\n”,p—〉data。
num,p—>data。
name,p-〉data。
gender,p->data。
score);printf("———---—-—----—--—-————-——---—--——-—--——---——-——-——-----——----—-—-—\n”);
}
else
printf("没查到要查询的学生信息!");
break;
case 4:
printf("**************************************\n”);
printf("删除学生信息\n");
printf("**************************************\n”);
delNode(head);
break;
case 5:
printf(”**************************************\n”);
printf("修改学生信息\n”);
printf(”**************************************\n");
changeNode(head);
break;
case 6:
printf("**************************************\n”);
printf("输出所有学生信息\n”);
printf("**************************************\n”);
printList(head);
break;
case 0:
printf(”再见!\n作者:CBH\n");
getchar();
return;
}
}
}
菜单程序:
int menu_select()
{
int sn;
printf("\n 学生信息管理系统\n”);
printf(”=========================================\n”);
printf(" 1.学生信息链表的建立\n”);
printf(" 2.插入学生信息\n”);
printf(" 3。
查询学生信息\n”);
printf(" 4.删除学生信息\n");
printf(” 5.修改学生信息\n”);
printf(" 6。
输出所有学生信息\n”);
printf(” 0.退出管理系统\n");
printf("==========================================\n");
printf("请选择0-6:\n”);
scanf(”%d",&sn);
for(;sn<0 || sn>6;)//判断是否选择范围在0到6,超出范围重新选择
{
printf(”\n输入错误,重选0—6\n”);
scanf("%d",&sn);
}
return sn;
}
(7)过程和函数的调用关系图2反映了演示程序的层次结构: (其中菜单是人与程序交流的桥梁,删除和修改信息均基于查询信息函数功能)
图2 演示程序层次结构
1.4 调试分析
(1)在创建链表的过程中,需要使得尾结点正确的指向到开辟的结点位置,并
且循环指向,使得信息正确输入链表中;在插入信息的过程中,需要处理好新结
点对旧结点的链接;在修改信息的过程中,只需要对找到的结点进行赋值覆盖即
可;在删除结点的过程中,需要使得需移除的结点从链表中释放。
(2)本程序的模块划分比较合理,且尽可能将指针的操作封装在结点和链表的
两个模块中,致使模块的调试比较顺利。
函数之间也能够相互的调用,使得程序
的可视性和可调性更多。
并且界面操作简介方便。
(3)本程序的主程序同功能程序的衔接十分自然,算法效率高.
(4)本实习作业采用数据抽象的程序设计方法,将程序划分为四个层次结构:元
素结点、线性链表、函数和主控模块,使得设计时思路清晰,实现时调试顺利,
各模块具有较好的可重用性,确实得到了一次良好的程序设计训练。
1。
5 用户手册
(1)本程序的运行环境为VC++6.0操作系统,执行文件为:学生成绩管理系
统.exe,如图3
图3 运行环境
(2)执行程序后即显示用户界面,如图4
图4 用户界面
(3)选择1进入链表创立,如图5
图5 链表创立
(4)选择2进入插入界面,如图6
图6 插入界面 (5)选择3进入查询界面,如图7
图7 查询界面 (6)选择4进入删除界面,如图8
图8 删除学生信息
(7)选择5进入修改界面,如图9
图9 修改界面
(8)选择6输出界面
(9)选择0退出界面
1.6测试结果
1. 学生链表建立,如图10
图10 链表建立
2. 插入学生信息及其位置,如图11
图11 插入信息与位置
3。
查询学生信息(学号),如图12
图12 通过学号查询学生信息
4. 查询学生信息(姓名),如图13
图13 通过姓名查询学生信息
5。
修改学生信息,如图14
图14 修改学校信息
6. 删除学生信息,如图15
图15 删除学生信息
7。
输出所有学生信息,如图16
图16 输出所有信息
8. 退出管理系统,如图17
图17 退出管理系统。