数据结构实验报告线性表顺序存储结构1.docx
《数据结构实验报告线性表顺序存储结构1.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告线性表顺序存储结构1.docx(15页珍藏版)》请在冰豆网上搜索。
![数据结构实验报告线性表顺序存储结构1.docx](https://file1.bdocx.com/fileroot1/2022-12/14/6f6c113d-da2b-4e54-8568-ffa9db3ae49b/6f6c113d-da2b-4e54-8568-ffa9db3ae49b1.gif)
数据结构实验报告线性表顺序存储结构1
实验报告
课程名称:
数据结构实验名称:
线性表的顺序存储结构
班级:
学生姓名:
学号:
指导教师评定:
签名:
题目:
有两张非递减有序的线性学生表A,B,采用顺序存储结构,两张表合并用c表存,要求C仍为非递减有序的,并删除C中值相同的表。
一、需求分析
⒈本演示程序根据已有的6位学生的信息,实现两张表的合并及删除值相同元素的操作,不需要用户重新输入学生的信息。
⒉在演示过程序中,用户敲击键盘,即可观看演示结果。
⒊程序执行的命令包括:
(1)构造线性表A
(2)构造线性表B(3)求两张表的并(4)删除C中值相同的元素
二、概要设计
⒈为实现上述算法,需要线性表的抽象数据类型:
ADTStack{
数据对象:
D={ai:
|ai∈ElemSet,i=1…n,n≥0}
数据关系:
R1={|ai-1,ai∈D,i=2,…n≥0}
基本操作:
init(list*L)
操作结果:
构造一个空的线性表L。
ListLength(List*L)
初始条件:
线性表L已经存在
操作结果:
返回L中数据元素的个数。
GetElem(ListL,inti,ElemType*e)
初始条件:
线性表L已经存在,1≤i≤ListLength(&L)
操作结果:
用e返回L中第i个数据元素的值。
EqualList(ElemType*e1,ElemType*e2)
初始条件:
数据元素e1,e2存在
操作结果:
以e1,e2中的姓名项作为判定e1,e2是否相等的依据。
Less_EquaList(ElemType*e1,ElemType*e2)
初始条件:
数据元素e1,e2存在
操作结果:
以e1,e2中的姓名项(为字符串)的≤来判定e1,e2是否有≤的关系。
LocateElem(List*La,ElemTypee,inttype)
初始条件:
线性表La已经存在
操作结果:
判断La中是否有与e相同的元素。
MergeList(List*La,List*Lb,List*Lc)
初始条件:
非递减线性表La,Lb已经存在
操作结果:
合并La,Lb得到Lc,Lc仍按非递减有序排列。
UnionList(List*La,List*Lb)
初始条件:
线性表La,Lb已经存在
操作结果:
将所有在Lb而不在La中的元素插入到La中表尾的位置。
PrintList(ListL)
初始条件:
线性表L已经存在
操作结果:
打印出表L。
ListInsert(List*L,inti,structSTUe)
初始条件:
线性表L已经存在,1≤i≤ListLength(&L)+1
操作结果:
在表L中第i个位置前插入元素e,L的长度加1。
}ADTList
2.本程序有三个模块:
⑴主程序模块
voidmain(){
初始化;
{
接受命令;
显示结果;
}
}
⑵线性表单元模块:
实现线性表抽象数据类型;
⑶结点结构单元模块:
定义线性表中的结点结构。
三、详细设计
⒈元素类型,结点类型
structSTU{
charname[20];//学生名字、学号、年龄、分数
charstuno[10];
intage;
intscore;
};
typedefstructSTUElemType;//元素类型
structLIST{
ElemType*elem;
intlength;//表的长度、大小
intlistsize;
};
typedefstructLISTlist;//结点类型
2.对抽象数据类型中的部分基本操作的伪码算法如下:
intinit(List*L)
{
L→elem=(ElemType*)malloc(sizeof(ElemType)*LIST_INIT_SIZE);
If(!
L→elem)exit(OVERFLOW);
L→length=0;
L→listsize=LIST_INIT_SIZE;
ReturnOK;
}//初始化表
intListLength(List*L)
{
returnL→length;
}//返回表长
voidGetElem(ListL,inti,ElemType*e)
{
*e=L.elem[i];
}//返回元素
intlocateElem(List*La,ElemTypee,inttype)
{
intI;
switch(type)//确定元素在表中的位置
{
caseEQVAL;
for(i=0;iif(EqualList(&La→elem[i],&e))
return1;break;
default;
break;
}
return0;
}
voidMergeList(List*La,List*Lb,List*Lc)
{//将两个表合并成Lc
ElemType*pa,*pb,*pc,*pa_last,*pb_last;
Pa=La→elem;pb=Lb→elem;
Lc→Listsize=Lc→length=La→length+Lb→length;
Pc=Lc→elem==(ElemType*)malloc(Lc→listsize*sizeof(ElemType));
if(!
Lc→elem)exit(OVERFLOW);
pa_last=La→elem+La→length-1;
pb_last=Lb→elem+Lb→length-1;
while(pa<=pa_last&&pb<=pb_last)
{
if(Less_EqualList(pa,pb))*pc++=*pa++;
else*pc++=*pb++;
}
while(pa<=pa_last)*pc++=*pa++;
while(pb<=pb_last)*pc++=*pb++;
}
voidUnionList(List*La,List*Lb)
{
La_len=ListLength(La);Lb_len=ListLength(Lb);
For(i=0;i{
GetElem(*Lb,i,&e);
If(!
LocateElem(La,e,EQUAL))
ListInsert(La,++La_len,e);
}
}
intListInset(List*L,inti,structSTUe)
{//将元素插入表L中
if(i<1||i>L→length+1)returnERROR;
q=&(L→elem[i-1]);
for(p=L→elem[L→length-1];p>=q;p--)
*(p+1)=*p;
*q=e;
++(L→length);
returnOK;
}//ListInsertBeforei
3.主函数和其他函数的伪码算法
voidmain()
{
Initialization();//初始化
ReadCommand(cmd);//读入一个操作符
MakeList(La);printList(La);//产生并打印La
MakeList(Lb);printList(Lb);//产生并打印Lb
OperateList(La,Lb);
}
voidInitialization()
{//系统初始化
clrscr();
}
intReadCommand(cmd)//任意键入一个字符
{
cmd=getch();
return1;
}
voidMakeList(La)
{
ListInsert(&La,i,e);
}
voidOperateList(La,Lb)
{
MergeList(&La,&Lb,&Lc);
UnionList(&La,&Lb);
}
4函数调用关系
main
InitializationMakeListOperateListReadCommandprintList
UnionListMergeList
Less_EqualList
InitListInsertLocateElem
EqualList
四、调试分析
⒈刚开始输入时,漏掉了一些变量参数的标记"&",有的则错加了"&",使得程序运行出来的结果不正确,使调试程序时费时不少。
⒉程序采用逐个输入的方法创建La,Lb,在元素较多时,会使得程序很庞大,不利于检查错误等。
⒊算法的时空分析
各操作的算法时间复杂度比较合理
init,ListLength,GetElem,EqualList,Less_EqualList为O
(1)
LocateElem,ListInsert,printList为O(n),UnionList为O(mn),MergeList为O(n)。
4.本次实验采用数据抽象的程序设计方法,将程序化为三层次结构,设计时思路清晰,使调试也较顺利,各模块有较好的可重用性。
五、用户手册
⒈本程序的运行环境为windowsxp操作系统,执行文件为Exp1Prb1.c;
⒉进入演示程序后,完成编译,连接(即同时按下CtrlF9)进入演示界面,用户键入任一符号,都能看完整个演示过程。
六、测试结果
(1)同时键入CtrlF9,演示为:
-----------------ListDemoisrunning--------------
FirstisInsertListfunction
namestunoagescore
stu1100001801000
stu3100002801000
(2)键入任意字符,演示为:
namestunoagescore
stu1100001801000
stu3100002801000
stu5100003801000
ListAlengthnowis3.
(3)键入任意字符,演示为:
namestunoagescore
stu2100001801000
stu4100002801000
stu6100001801000
ListBlengthnowis3.
(4)键入任意字符,演示为:
namestunoagescore
stu1100001801000
stu2100001801000
stu3100002801000
stu4100002801000
stu5100003801000
stu6100001801000
SecondisUnionListfunction.
NowunionListAandListB...
namestunoagescore
stu1100001801000
stu2100002801000
stu3100003801000
stu4100001801000
stu5100002801000
stu6100001801000
ListAlengthnowis6.
(5)键入任意字符,退出演示界面,回到编辑状态。
七、附录:
题一源程序
//------头文件
#include
#include
#include
//符号常量
#defineERRORO
#defineOK1
#defineEQUAL1
#defineOVERFLOW-1
#defineLIST_INIT_SIZE100//线性表存储空间的初始分配量
#defineLISTINCREMENT10//线性表存储空间的分配增量
//类型声明
structSTU{//定义学生结构体类型,包括姓名,学号,年龄,成绩
charname[20];
charstuno[10];
intage;
intscore;
}stu[50];
typedefstructSTUElemType;//用ElemType代替学生
structLIST
{//定义表LIST为结构体类型
ElemType*elem;//存储空间基址
intlength;//当前长度
intlistsize;//当前分配的存储容量
};
typedefstructLISTList;//用list代表结构体LIST
intinit(List*L)
{//构造一个空的线性表
L→elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
If(!
L→elem)exit(OVERFLOW);//存储分配失败
L→length=0;//空表长度为0
L→listsize=LIST_INIT_SIZE;//初始存储容量
Returnok;
}
intListLength(List*L)
{//求表L的长度
returnL→length;
}
voidGetElem(ListL,inti,ElemType*e)
{
*e=L.elem[i];
}
intEqualList(ElemType*e1,ElemType*e2)
{//以元素e1,e2中的姓名项是否相等作为判定e1,e2是否相等的标准
if(strcmp(e1→name,e2→name)==0)
return1;
else
return0;
}
intLess_EqualList(ElemType*e1,ElemType*e2)
{//以姓名(字符串)的≤作为判定e1≤e2的标准
if(strcmp(e1→name,e2→name)<=0)
return1;
else
return0;
}
intLocateElem(List*La,ElemTypee,inttype)
{//判断La中是否有与e符合关系type的元素
inti;
suitch(type)
{
caseEQUAL;
for(i=0;iif(EqualList(&La→elem[i],&e))
return1;
break;
default;break;
}
return0;
}
voidMergeList(List*La,List*Lb,List*Lc)
{//合并表La,Lb,用Lc存储。
已知La,Lb元素值按非递减排列,Lc中值也按非递减排列
ElemType*pa,*pb,*pc,*pa_last,*pb_last;
pa=La→elem;pb=Lb→elem;
Lc→listsize=Lc→length=La→length+Lb→length;
Pc=Lc→elem=(ElemType*)malloc(Lc→listsize*sizeof(ElemType));
if(!
Lc→elem)exit(OVERFLOW);//存储分配失败
pa_last=La→elem+La→length-1;
pb_last=Lb→elem+Lb→length-1;
while(pa<=pa_last&&pb<=pb_last)
{//合并,Lc元素按非递减排列
if(Less_EqualList(pa,pb))*pc++=*pa++;
else*pc++=*pb++;
}
while(pa<=pa_last)*pc++=*pa++//插入La的剩余元素
while(pb<=pb_last)*pc++=*pb++//插入Lb的剩余元素
}
voidUnionList(List*La,List*Lb)
{//将所有在Lb中而不在La中的元素插入到La中
intLa_len,Lb_len;
inti;
ElemTypee;
La_len=Listlength(La);Lb_len=Listlength(Lb);//求线性表长度
for(i=0;i{
GetElem(*Lb,I,&e);
If(!
LocateElem(La,e,EQUAL))
ListInsert(La,++La_len,e);
}
}
intprintlist(ListL)
{//输入表L
inti;
printf("namestunoagescore\n");
for(i=0;iprintf("%-cos%s\t%d\t%d\n",L.elem[i].name,L.elem[i].stuno,L.elem[i].age,L.elem[i].score);
printf("\n");
}
intListInsert(List*L,inti,structSTUe)
{//在表L中第i位上插入e
structSTU*p,*q;
if(*i<1||i>L→length+1)returnERROR;//i值不合法
q=&(L→elem[i-1]);
for(p=&L→elem[L→length-1];p>=q;--p)
*(p+1)=*p;
*q=e;
++L→length;
returnok;
}
main
{
structSTUe;//定义结构体变量e
ListLa,Lb,Lc;//定义结构体变量,即表La,Lb,Lc
Clrscr();
Printf("\n\n--------ListDemoisrunning----------\n\n");
Printf("FirstisInsertListfunction.\n");
init(&La);//创建一个新表La
strcpy(e.name,"stu1");
strcpy(e.stuno,"100001");
e.age=80;
e.score=1000;
ListInsert(&La,1,e);//在La的第1位上插入stu1的数据元素
strcpy(e.name,"stu3");
strcpy(e.stuno,"100002");
e.age=80;
e.score=1000;
ListInsert(&La,2,e);//在La的第2位上插入stu3的数据元素
Printlist(La);//输出La
Printf("ListAlengthnowis%d.\n\n",La.length);
Getch();
strcpy(e.name,"stu5");
strcpy(e.stuno,"100003");
e.age=80;
e.score=1000;
ListInsert(&La,3,e);//在表La的第3位上插入stu5的数据表
printlist(La);//输出表La
printf("ListAlengthnowis%d.\n\n",La.length);
getch();
init(&Lb);//创建一张新表Lb
strcpy(e.name,"stu2");
strcpy(e.stuno,"100001");
e.age=80;
e.score=1000;
ListInsert(&Lb,1,e);//在表Lb的第1位上插入stu2的数据
strcpy(e.name,"stu4");
strcpy(e.stuno,"100002");
e.age=80;
e.score=1000;
ListInsert(&Lb,2,e);//在表Lb的第2位上插入stu4的数据
strcpy(e.name,"stu6");
strcpy(e.stuno,"100001");
e.age=80;
e.score=1000;
ListInsert(&Lb,3,e);//在表Lb的第3位上插入stu6的数据
printlist(Lb);//输出表Lb
printf("ListBlengthnowis%d.\n\n",Lb.length);
getch();
MergeList(&La,&Lb,&Lc);//合并表La,Lb,用表Lc存储(非递减有序)
Printlist(Lc);//输出表Lc
getch();
printf("SecondisUnionListfunction.\n");
printf("NowUnionListAandListB---\n");
UnionLIst(&La,&Lb);//合并La,Lb,并删除值相同的元素,用La存储
Printlist(La);//输出La
Printf("ListAlengthnowis%d.\n\n",La.length);
getch();
}