数据结构实验报告顺序表.docx
《数据结构实验报告顺序表.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告顺序表.docx(28页珍藏版)》请在冰豆网上搜索。
数据结构实验报告顺序表
《算法与数据结构》课程
实验报告
一、实验目的
1、实现线性表的顺序存储结构。
2、熟悉C++程序的基本结构,掌握程序中的头文件、实现文件和主文件之间的相互关系及各自的作用。
3、熟悉顺序表的基本操作方式,掌握顺序表相关操作的具体实现。
二、实验内容及要求
对顺序存储的线性表进行一些基本操作。
主要包括:
(1)插入:
操作方式为在指定元素前插入、在指定元素之后插入、在指定位置完成插入。
(2)删除:
操作方式可分为删除指定元素、删除指定位置的元素等,尝试实现逻辑删除操作。
(3)显示数据。
(4)查找:
查询指定的元素(可根据某个数据成员完成查询操作)。
(5)定位操作:
定位指定元素的序号。
(6)更新:
修改指定元素的数据。
(7)数据文件的读写操作等。
其它操作可根据具体需要自行补充。
要求线性表采用类的定义,数据对象的类型自行定义。
三、系统分析
(1)数据方面:
能够实现多种数据类型顺序表的创建,并进行操作,不同的数据类型数据使用不同的文本文件保存。
(2)功能方面:
能够实现线性表的一些基本操作,主要包括:
1.计算表最大可以容纳表项个数以及当前表的当前长度。
2.能够进行添加操作,在已有的数据文件中进行数据的添加。
3.能够进行搜索操作,返回搜索项在表中表项序号
4.能够进行定位操作,定位到表中合理位置。
5.能够进行取值操作,根据用户需求取出表中某项的值。
6.能够进行修改操作,在用户选择修改项后将重新输入内容修改到对应位置。
7.能够进行插入操作,在用户选择合理位置并输入插入内容后即可。
8.能够进行删除操作,用户根据选择表中项数删除对应数据。
9.能够进行判断表空或表满。
四、系统设计
(1)设计的主要思路
根据实验要求,首先将顺序表模板类完成,并将需要实现的功能代码完善,在写实现各个功能的菜单并将模板类实例化为简单数据类型最后进行调试,由于还需使得顺序表能够存储自定义的学生类类型数据,故根据要求写出Student类,并将之前所写得模板类用学生类数据类型实例化,再进行调试。
最后在建立一个菜单可以进行选择不同的数据类型,最后将两个菜单进行关联,使得通过一个顺序表模板类能够实例化为实验要求的各个数据类型。
(2)数据结构的设计
顺序表是将所有表项按照其逻辑顺序依次存储到从计算机存储中指定存储位置开始的一块连续存储空间中。
并且对于顺序表所有表项,既可以顺序访问,也可以进行随机访问,各个表项的逻辑顺序与其存放的物理顺序一致,故在设计顺序表的结构时选择将数据基于数组存储,并通过数组的基本操作实现顺序表的功能。
(3)基本操作的设计
顺序表中的关键算法就是搜索、插入和删除操作。
搜索算法是通过顺序搜索实现的,在顺序表中搜索与给定值x匹配的表项,找到则返回该表项是第几个元素,否则函数返回0,表示搜索失败。
在搜索算法函数中通过传递用户需要搜索的数据。
插入算法主要是两步,第一步根据用户输入合理表中表项参数,然后在表中找出位置以及其后的元素往后移动一个位置,将插入的数据放在腾出的位置上。
插入算法函数有两个参数分别是位置参数以及插入的元素值。
删除算法则是通过用户输入定位到需要删除数据表项,然后将该数据之后的元素全部往前移动一个位置,将需要删除的数据进行覆盖。
顺序搜索算法流程图:
插入算法流程图:
删除算法流程图:
五、编程环境与实验步骤
(1)编程环境
操作系统:
Windows操作系统;编程工具软件:
VisualStudio2017
(2)实验步骤
程序相关文件为Student类文件、SeqList模板类文件、以及主函数调试文件main.cpp。
Student类文件为自定义的一个数据类型,包含学生的基本信息,并且通过重载输入输出操作符实现在SeqList模板类中能够成功调试。
SeqList模板类中主要包括一些功能实现的函数。
主函数调试文件则是对于不同数据类型在一个模板类中完成调试,以及顺序表基本功能的实现。
(3)编译参数
无编译参数,在Vs2017或其他版本中新建项目然后将三个文件main.cpp、SeqList.h、Student.h添加到解决方案中的头文件中调试即可。
六、实现代码
Main.cpp中代码:
#include
#include
#include"SeqList.h"
#include"Student.h"
stringstr="";
template
voidmenu(T&y,stringstr);
intmain(){
boolfin=false;
intch;//用户选择
while(!
fin){
cout<<"*****请用户选择顺序表数据类型*****"<cout<<"-------------1.整数型-------------"<cout<<"-------------2.浮点型-------------"<cout<<"-------------3.双浮点型-----------"<cout<<"-------------4.字符型-------------"<cout<<"-------------5.学生信息型---------"<cout<<"-------------6.退出---------------"<cout<<"请输入你的选择[1-6]:
"<cin>>ch;
switch(ch){
case1:
intx1;
str="int";
menu(x1,str);
break;
case2:
floatx2;
str="float";
menu(x2,str);
break;
case3:
doublex3;
str="double";
menu(x3,str);
break;
case4:
{
stringx4;
str="string";
menu(x4,str);
break;
}
case5:
{
Studentx5;
str="student";
menu(x5,str);
break;
}
case6:
fin=true;
break;
default:
cout<<"输入选择错误,请重新输入!
"<}
}
system("pause");
return0;
}
template
voidmenu(T&y,stringstr){
intlen,maxSize,choose,locate;
SeqLists;
Tx;
inti;
intfini=0;
while(!
fini){
cout<<"-----------1:
文件操作建立新顺序表-------------"<cout<<"-----------2:
在之前所选数据文件中数据进行操作-"<cout<<"-----------3:
顺序表的最大可容纳表项个数-------"<cout<<"-----------4:
顺序表的长度---------------------"<cout<<"-----------5:
搜索x在表中的位置----------------"<cout<<"-----------6:
定位到第i个表项------------------"<cout<<"-----------7:
取第i个表项的值------------------"<cout<<"-----------8:
用x修改第i个表项的值-------------"<cout<<"-----------9:
在第i个表项后插入元素x-----------"<cout<<"-----------10:
删除第i个表项-------------------"<cout<<"-----------11:
判断表是否为空------------------"<cout<<"-----------12:
判断表满否----------------------"<cout<<"-----------13:
文件操作保存数据----------------"<cout<<"-----------14:
退出:
--------------------------"<cout<<"请输入你的选择[1-14]:
"<cin>>choose;
switch(choose){
case1:
s.Inputfile();
break;
case2:
{
s.InputfileAppend();
break;
}
case3:
maxSize=s.Size();
cout<<"顺序表的最大可容纳表项个数为:
"<break;
case4:
len=s.Length();
cout<<"顺序表的长度为:
"<break;
case5:
cout<<"请输入要搜索的值x:
"<cin>>x;
i=s.Search(x);
if(i==0)
cout<<"顺序表中无此值"<else
{
cout<cout<cout<<"该数据在表中的第"<
}
break;
case6:
cout<<"请输入要定位的位置i:
";
cin>>i;
locate=s.Locate(i);
if(locate!
=-1)
cout<<"定位成功!
在顺序表中下标为:
"<else
cout<<"定位失败!
"<break;
case7:
cout<<"请输入要取表中元素的位置i:
";
cin>>i;
if(s.getData(i,x)){
cout<<"表中第"<
"<cout<}
else
cout<<"取值失败!
检查是否超范围取值"<break;
case8:
cout<<"请输入要修改的位置i和值x:
"<cout<<"表中位置:
";cin>>i;
cout<<"修改值:
"<>x;
s.setData(i,x);
break;
case9:
cout<<"请输入要插入的位置i和值x:
"<cout<<"表中位置:
";cin>>i;
cout<<"插入值:
"<>x;
if(s.Insert(i,x))
cout<<"插入成功!
"<else
cout<<"插入失败!
"<break;
case10:
cout<<"请输入要删除的表项的位置i:
";
cin>>i;
if(s.Remove(i,x)){
cout<<"删除成功!
删除的值为:
"<cout<}
else
cout<<"删除失败!
"<break;
case11:
if(s.IsEmpty())
cout<<"表为空!
"<else
cout<<"表不为空!
"<break;
case12:
if(s.IsFull())
cout<<"表满!
"<else
cout<<"表未满!
"<break;
case13:
s.Outputfile();
cout<<"保存成功!
"<break;
case14:
{
fini=1;
return;
}
default:
cout<<"输入选择错误,请重新输入!
"<}
}
}
SeqList.h代码:
#include
#include
constintdefaultSize=100;
usingnamespacestd;
externstringstr;
template
classSeqList{
protected:
T*data;//存放数组
intmaxSize;//最大可容纳表项的项数
intlast;//当前已存表项的最后位置(从0开始)
voidreSize(intnewSize);//改变data数组空间大小
public:
SeqList(intsz=defaultSize);
SeqList(SeqList&L);
intSize(){//计算表最大可容纳表项个数
returnmaxSize;
}
intLength(){//计算表长度
returnlast+1;
}
intSearch(T&x);
intLocate(inti);
boolgetData(inti,T&x){//取出表中第i个表项得值
if(i>0&&i<=last+1){
x=data[i-1];
returntrue;
}
else{
returnfalse;
}
}
voidsetData(inti,T&x){//用x修改表中第i个表项之后
if(i>0&&i<=last+1){
data[i-1]=x;
stringa=".txt";
fstreamfile(str+a,ios:
:
out);
for(intj=0;j<=last;j++){
file.write((char*)&data[j],sizeof(data[j]));
}
file.close();
}
}
boolInsert(inti,T&x);
boolRemove(inti,T&x);
boolIsEmpty(){//判断表是否为空,空则返回true,非空返回false
return(last==-1)?
true:
false;
}
boolIsFull(){//判断表是否满,满则返回true,否则返回false
return(last==maxSize-1)?
true:
false;
}
voidInputfile();
voidOutputfile();
voidInputfileAppend();
SeqListoperator=(SeqList&L);
};
/**
*构造函数
*通过指定参数sz定义数组的长度
*/
template
SeqList:
:
SeqList(intsz){
if(sz>0){
maxSize=sz;last=-1;//置表的实际长度为空
data=newT[maxSize];//创建顺序表存储数组
if(data==NULL){//动态分配失败
cerr<<"存储分配错误!
"<(1);
}
}
}
/**
*复制构造函数
*用参数表中给出的已有顺序表初始化新建的顺序表
*/
template
SeqList:
:
SeqList(SeqList&L){
maxSize=L.Size();last=L.Length()-1;Tvalue;
data=newT[maxSize];//创建顺序表存储数组
if(data==NULL){//动态分配失败
cerr<<"存储分配错误!
"<(1);
}
for(inti=1;i<=last+1;i++){
L.getData(i,value);data[i-1]=value;
}
}
/**
*改变data数组空间大小
*私有函数:
扩充顺序表的存储数组空间大小,新数组的元素个数为newSize
*/
template
voidSeqList:
:
reSize(intnewSize){
if(newSize<=0)//检查参数的合理性
{
cerr<<"无效的数组大小"<}
if(newSize!
=maxSize){//修改
T*newarray=newT[newSize];
if(newarray==NULL){
cerr<<"存储分配错误!
"<(1);
}
intn=last+1;
T*srcptr=data;//源数组首地址
T*destptr=newarray;//目的数组首地址
while(n--){
*destptr++=*srcptr++;//复制
}
delete[]data;//删除老数组
data=newarray;maxSize=newSize;//复制新数组
}
}
/**
*搜索函数:
搜索x在表中位置,返回表项序号
*在表中顺序搜索与给定值x匹配的表项,找到则函数返回该表项是第几个元素,否则函数返回0,表示搜索失败
*/
template
intSeqList:
:
Search(T&x){
for(inti=0;i<=last;i++)
if(data[i]==x)
returni+1;
return0;
}
/**
*定位函数:
定位第i个表项,函数返回表项序号
*函数返回第i(不超过数组范围)个表项的位置,否则函数返回0,表示定位失败。
*/
template
intSeqList:
:
Locate(inti){
if(i>=1&&i<=last+1)
returni-1;
else
return0;
}
/**
*插入函数:
插入x在第i个表项之后
*将新元素x插入到表中第i个(不超过数组范围)表项之后。
函数返回插入成功的信息,若插入成功则返回true,否则返回false.
*/
template
boolSeqList:
:
Insert(inti,T&x){
if(last==maxSize-1)//表满不能插入操作
{
returnfalse;
}
if(i<0||i>last+1)//参数i不合理,不能插入
returnfalse;
for(intj=last;j>=i;j--){
data[j+1]=data[j];//依次后移,为x腾出位置
}
data[i]=x;//插入
last++;//表中最后位置加1
stringa=".txt";
fstreamfile(str+a,ios:
:
out);
for(intj=0;j<=last;j++){
file.write((char*)&data[j],sizeof(data[j]));
}
file.close();
returntrue;//成功插入
}
/**
*删除函数:
删除第i个表项,通过x返回表项的值
*从表中删除第i(不超过数组范围)个表项,通过引用型参数x返回删除的元素值。
*函数返回删除成功的信息,若删除成功则返回true,否则返回false。
*/
template
boolSeqList:
:
Remove(inti,T&x){
if(last==-1)//表空不能删除
returnfalse;
if(i<1||i>last+1)//参数i不合理
returnfalse;
x=data[i-1];//存在被删除元素
for(intj=i;j<=last;j++){
data[j-1]=data[j];//依次往前移动
}
last--;//表中最后位置减1
stringa=".txt";
fstreamfile(str+a,ios:
:
out);
for(intj=0;j<=last;j++){
file.write((char*)&d