线性表的基本操作西华大学数据结构.docx
《线性表的基本操作西华大学数据结构.docx》由会员分享,可在线阅读,更多相关《线性表的基本操作西华大学数据结构.docx(12页珍藏版)》请在冰豆网上搜索。
线性表的基本操作西华大学数据结构
数学与计算机学院
实验报告
(2011/2012学年第1学期)
课程名称
数据结构
课程代码
实验时间
2011
年
11
月
16
日
指导单位
软件工程系
指导教师
周立章
学生姓名
年级
10
学号
专业
Web与移动平台技术
实验成绩
实验名称
学生成绩管理系统
指导教师
周立章
实验类型
设计
实验学时
2+10
实验时间
一、实验目的和要求
(1)掌握线性表的顺序存储结构,在顺序存储结构基础上进行的插入、删除、查找等算法的思想和实现;
(2)掌握线性表的链式存储结构。
掌握线性表的链式存储结构的建立。
在链表中插入、删除和查找算法的思想和算法实现。
(3)掌握线性表在顺序存储、链式存储结构的基础进行的各种应用。
(4)掌握链表的定义和基础知识以及链表的存储和链式存储结构及其应用。
(5)掌握队列的基础知识,循环顺序队列、链队列及其应用。
(6)会用结构体正确描述每一条学生记录的信息,掌握链表结构存储所处理的数据。
(7)设计友好的人机交互菜单,通过相应的流程控制语句的正确使用,使得在主函数中体现对各功能模块的调用,从而实现一个完整的小型管理系统。
要求:
课内实验学时2学时,课后学时要求为10学时。
二、实验环境(实验设备)
硬件:
微型计算机P4
软件:
WindowsXP+MicrosoftVisualC++6.0
三、实验原理及内容
实验题目利用链式存储结构存储学生的成绩信息,设计一个学生成绩管理系统,具有以下功能:
(1)定义学生结构体类型structStudent,每个学生包括学号、姓名、3门功课(课程名自己定义)、总分。
(2)建立双向循环链表:
输入若干学生的信息(当输入学生的学号为0000时结束,要求自动计算总分),并按输入的顺序建立双向循环链表;
(3)输出学生成绩信息:
遍历双向循环链表,输出所有学生的完整信息到屏幕;
(4)查找指定学号的学生信息。
如果查找成功,输出所有学生信息,否则输出失败。
(5)插入学生信息:
以队列的方式将新学生成绩信息插入到链表中;
(6)删除学生信息:
给出学生姓名,删除链表所有相同姓名的学生的信息(即姓名相同的结点);
(7)修改学生信息:
给出学生学号,修改该生的三门课程成绩信息;
(8)按总分排序:
在原来的双向循环链基础上按总分降序进行就地排列。
即不能增加额外的空间开销;
实验前准备:
完成上述
(1)-(4)算法,并要求上机验证通过。
实验时完成(5)-(6)。
实验后,完成算法(7),(8),并要求上机验证通过。
实验解答:
1)画出主函数的流程图
2)数据类型定义
(1)学生成绩信息结构体类型的定义
typedefstructStudent
{
intID;
charname[10];
intzongs;
intscore[3];
structStudent*prior,*next;
}DNode;
(2)双向链表结点的定义。
是否将结点的数据类型定义为学生成绩信息结构体类型?
是。
3)为了能够完成链表的各项操作,你给出的测试数据有哪些?
主要用于测试哪些方面?
1.ID=101,name=z,score[0]=11,score[1]=11,score[2]=11//测试链表的建立
2.ID=102,name=x,score[0]=22,score[1]=22,score[2]=22//测试链表的建立
3.ID=-999//测试输入完成
4.i=1//菜单选项
ID=103,name=c,score[0]=33,score[1]=33,score[2]=33//测试增加学生信息
5.i=2//菜单选项
ID=101,score[0]=12,score[1]=12,score[2]=12//测试修改学生信息——成功
6.i=2//菜单选项
ID=100//测试修改学生信息——错误
7.i=3//菜单选项
ID=101//测试查找学生信息——成功
8.i=3//菜单选项
ID=100//测试查找学生信息——错误
9.i=4//菜单选项
ID=c//测试删除学生信息——成功
10.i=4//菜单选项
ID=100//测试删除学生信息——错误
11.i=5//菜单选项//测试显示学生信息——成功
12.i=6菜单选项//测试学生信息排序——成功
13.i=7退出系统成功
实验报告
4)你是否在实验前完成了算法
(1)-(4)?
如果完成了难点在哪儿?
。
如果没有完成,理由是什么?
是之前完成的。
之前在完成的时候,没有编写测试代码,进行初步的程序测试,导致在后期的调试过程中出现了大量的错误。
花费大量的经历在调试程序上。
我觉得这个实验的难点在于自己对双向链表的理解以及把握上。
只要自己对双向链表的理解以及把握能够进一步提高,那么我相信自己在编写这个程序的时候一定会得心应手的。
5)建立双向循环链表,你采用的是后插法还是前插法?
写出C++语言代码。
后插法。
voidStudentLink:
:
CreatLink()
{
head=newDNode;
head->prior=head->next=head;
DNode*s,*p;
s=newDNode;
cout<<"请依次输入学号、姓名、语数外三科成绩(学号为-999是结束):
"<cin>>s->ID;
p=head;
do{
cin>>s->name>>s->score[0]>>s->score[1]>>s->score[2];
s->zongs=s->score[0]+s->score[1]+s->score[2];
s->prior=p;p->next=s;s->next=head;head->prior=s;p=s;
cout<<"请依次输入学号、姓名、语数外三科成绩(学号为-999是结束):
"<s=newDNode;
cin>>s->ID;
}while(s->ID!
=-999);
cout<<"学生信息录入完毕!
"<}
6)、遍历双向循环链表时,你是如何判断遍历结束的?
如何控制对结点的访问?
给出算法的代码。
遍历结束的标志是指针指导了头节点。
voidStudentLink:
:
Show()/
{
DNode*p;
p=head->next;
do{
cout<<"学号:
"<ID<cout<<"姓名:
"<name<cout<<"语文:
"<score[0]<cout<<"数学:
"<score[1]<cout<<"英语"<score[2]<cout<<"总分"<zongs<p=p->next;
}while(p!
=head);
cout<<"信息显示完毕!
"<}
7)在循环双向链表中,有几种方法可以取链表中的首元结点?
写出表达式。
我知道的一共有2中取链表中首元结点的方法:
p=head->next
p=head->next->next->piror;
8)插入算法:
当按队列的方式进行插入运算时,新学生信息是插入到什么位置?
写出算法。
链表末尾。
voidStudentLink:
:
Add()
{
DNode*s,*p;
s=newDNode;
cout<<"请依次输入学号、姓名、语数外三科成绩:
"<cin>>s->ID>>s->name>>s->score[0]>>s->score[1]>>s->score[2];
s->zongs=s->score[0]+s->score[1]+s->score[2];
p=head->prior;
s->prior=p;p->next=s;s->next=head;head->prior=s;
cout<<"增加完毕"<}
9)如果要求将新学生信息插入到链表中指定的i位置,写出插入算法的代码,并给出时间复杂度。
这个之前没有做。
10)删除操作:
在该删除中,时间开销主要用在什么地方?
写出删除算法的代码,给出时间复杂度。
它与顺序表中同样的删除上有什么不同?
你是如何保证删除了所有姓名相同的结点的?
在这个算法中,花费时间最多的在于查找这个人的时间花费上。
为了保证所有相同姓名的人都删除掉,我在设计的时候是一边找,一边删除。
即找到一个就删除掉,然后有继续查找。
voidStudentLink:
:
Delete(chara[10])//删除学生信息
{
DNode*p;
p=head->next;
while(p!
=head)
{
if(strcmp(p->name,a)==0)
{
p->prior->next=p->next;
p->next->prior=p->prior;
cout<<"删除成功!
"<}
p=p->next;
}
cout<<"删除后:
"<Show();
}
11)写出修改学生成绩的代码
voidStudentLink:
:
Modify(intx)//修改学生信息
{
DNode*s;
s=head->next;
while(s->ID!
=x&&s->next!
=head){
s=s->next;
};
if(s->ID==x)
{
cout<<"你要修改的学生的信息:
"<ID<cout<<"请依次输入修改后的语数外三科成绩:
"<cin>>s->score[0]>>s->score[1]>>s->score[2];
s->zongs=s->score[0]+s->score[1]+s->score[2];
cout<<"修改成功!
"<}
else{cout<<"没有这个人!
"<}
12)按总分排序时,你是否增加了空间?
写出该算法的代码。
没有。
voidStudentLink:
:
Sort()
{
DNode*p,*q;
for(p=head->next;p->next!
=head;p=p->next)
{
for(q=p->next;q!
=head;q=q->next)
{
if(p->zongszongs)
{
if(p->next!
=q)
{
DNode*p2=p->next,*p1=p->prior;
p->prior->next=q;
p->next->prior=q;
p->prior=q->prior;
p->next=q->next;
q->prior->next=p;
q->next->prior=p;
q->next=p2;
q->prior=p1;
p=q;
}
else
{
p->prior->next=q;
q->next->prior=p;
p->next=q->next;
q->prior=p->prior;
p->prior=q;
q->next=p;
p=q;
}}}}
Show();
}
实验报告
四、实验小结(包括问题和解决方法、心得体会、意见与建议等)
1.在使用链表存储学生信息进行编程时,你所遇到的主要问题是什么,如何解决的?
在增加算法时,总是把原来的东西覆盖;查找、删除算法是又老是没有办法查找到第一个数据。
当时忙了很久才发现原来是链表指针出现了问题,所以就一个操作就显示一次,这样就很清晰明了的发现了问题的锁子啊,知道是什么原因了,就可以有的放矢的解决这一系列问题了。
2.链栈的进栈操作需什么条件?
栈操作的特点是什么?
条件:
操作前需验满,栈满就不能够进行进栈操作。
特点:
先出后进
3.队列操作的特点是什么?
如果Q表示是循环顺序队列,则表示Q为空的条件和满的条件是什么?
队列操作的特点是先进先出。
如果Q表示循环顺序队列,top==-1时表示栈空,如果top==MAX则表示栈满。
4.在删除算法中,你准备的测试数据是什么?
是否都按算法姓名相同的都删除?
数据是:
1.ID=101,name=z,score[0]=11,score[1]=11,score[2]=11
2.ID=102,name=x,score[0]=22,score[1]=22,score[2]=22
ID=103,name=z,score[0]=33,score[1]=33,score[2]=33
3.i=4//菜单选项
ID=z
4.i=4//菜单选项
ID=100/
按算法能够将所有的相同姓名信息删除。
5.对学生的成绩信息进行相关操作,你认为使用链式存储结构合理吗?
说明理由。
合理。
1、学生信息很多,不适合顺序储存方式,只能使用链式储存结构。
2、学生信息管理需要大量的操作,用栈操作也很方便对信息进行管理。
五、指导教师评语
成绩
批阅人
日期