线性表的存储结构定义及基本操作实验报告600724何俊林.docx
《线性表的存储结构定义及基本操作实验报告600724何俊林.docx》由会员分享,可在线阅读,更多相关《线性表的存储结构定义及基本操作实验报告600724何俊林.docx(37页珍藏版)》请在冰豆网上搜索。
![线性表的存储结构定义及基本操作实验报告600724何俊林.docx](https://file1.bdocx.com/fileroot1/2023-2/2/e1075c7a-7531-4f5b-a9ff-43f42276bc10/e1075c7a-7531-4f5b-a9ff-43f42276bc101.gif)
线性表的存储结构定义及基本操作实验报告600724何俊林
姓名:
何俊林学号:
201160072411软件工程1
线性表的存储结构定义及基本操作(实验报告)
一、实验目的:
.掌握线性表的逻辑特征
.掌握线性表顺序存储结构的特点,熟练掌握顺序表的基本运算
.熟练掌握线性表的链式存储结构定义及基本操作
.理解循环链表和双链表的特点和基本运算
.加深对顺序存储数据结构的理解和链式存储数据结构的理解,逐步培养解决实际问题的编程能力
二、实验内容
(一)基本实验内容(顺序表):
建立顺序表,完成顺序表的基本操作:
初始化、插入、删除、逆转、输出、销毁,置空表、求表长、查找元素、判线性表是否为空;
1.问题描述:
.利用顺序表,设计一组输入数据(假定为一组整数),能够对顺序表进行如下操作:
.创建一个新的顺序表,实现动态空间分配的初始化;
.根据顺序表结点的位置插入一个新结点(位置插入),也可以根据给定的值进行插入(值插入),形成有序顺序表;
.根据顺序表结点的位置删除一个结点(位置删除),也可以根据给定的值删除对应的第一个结点,或者删除指定值的所有结点(值删除);
.利用最少的空间实现顺序表元素的逆转;
.实现顺序表的各个元素的输出;
.彻底销毁顺序线性表,回收所分配的空间;
.对顺序线性表的所有元素删除,置为空表;
.返回其数据元素个数;
.按序号查找,根据顺序表的特点,可以随机存取,直接可以定位于第i个结点,查找该元素的值,对查找结果进行返回;
.按值查找,根据给定数据元素的值,只能顺序比较,查找该元素的位置,对查找结果进行返回;
.判断顺序表中是否有元素存在,对判断结果进行返回;
.编写主程序,实现对各不同的算法调用。
2.实现要求
对顺序表的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价;
.“初始化算法”的操作结果:
构造一个空的顺序线性表。
对顺序表的空间进行动态管理,实现动态分配、回收和增加存储空间;
.“位置插入算法”的初始条件:
顺序线性表L已存在,给定的元素位置为i,且1≤i≤ListLength(L)+1;操作结果:
在L中第i个位置之前插入新的数据元素e,L的长度加1;
.“位置删除算法”的初始条件:
顺序线性表L已存在,1≤i≤ListLength(L);操作结果:
删除L的第i个数据元素,并用e返回其值,L的长度减1;
.“逆转算法”的初始条件:
顺序线性表L已存在;
.操作结果:
依次对L的每个数据元素进行交换,为了使用最少的额外空间,对顺序表的元素进行交换;
.“输出算法”的初始条件:
顺序线性表L已存在;操作结果:
依次对L的每个数据元素进行输出;
.“销毁算法”初始条件:
顺序线性表L已存在;操作结果:
销毁顺序线性表L;
.“置空表算法”初始条件:
顺序线性表L已存在;操作结果:
将L重置为空表;
.“求表长算法”初始条件:
顺序线性表L已存在;操作结果:
返回L中数据元素个数;
.“按序号查找算法”初始条件:
顺序线性表L已存在,元素位置为i,且1≤i≤ListLength(L)操作结果:
返回L中第i个数据元素的值
.“按值查找算法”初始条件:
顺序线性表L已存在,元素值为e;操作结果:
返回L中数据元素值为e的元素位置;
.“判表空算法”初始条件:
顺序线性表L已存在;
.操作结果:
若L为空表,则返回TRUE,否则返回FALSE;
分析:
修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。
(二)基本实验内容(单链表):
建立单链表,完成链表(带表头结点)的基本操作:
建立链表、插入、删除、查找、输出、求前驱、求后继、两个有序链表的合并操作。
其他基本操作还有销毁链表、将链表置为空表、求链表的长度、获取某位置结点的内容、搜索结点。
1.问题描述:
利用线性表的链式存储结构,设计一组输入数据(假定为一组整数),能够对单链表进行如下操作:
.初始化一个带表头结点的空链表;
.创建一个单链表是从无到有地建立起一个链表,即一个一个地输入各结点数据,并建立起前后相互链接的关系。
又分为逆位序(插在表头)输入n个元素的值和正位序(插在表尾)输入n个元素的值;
.插入结点可以根据给定位置进行插入(位置插入),也可以根据结点的值插入到已知的链表中(值插入),且保持结点的数据按原来的递增次序排列,形成有序链表。
.删除结点可以根据给定位置进行删除(位置删除),也可以把链表中查找结点的值为搜索对象的结点全部删除(值删除);
.输出单链表的内容是将链表中各结点的数据依次显示,直到链表尾结点;
.编写主程序,实现对各不同的算法调用。
其它的操作算法描述略。
2.实现要求:
对链表的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,还要针对每个算法的实现从时间复杂度和空间复杂度上进行评价。
.“初始化算法”的操作结果:
构造一个空的线性表L,产生头结点,并使L指向此头结点;
.“建立链表算法”初始条件:
空链存在;操作结果:
选择逆位序或正位序的方法,建立一个单链表,并且返回完成的结果;
.“链表(位置)插入算法”初始条件:
已知单链表L存在;操作结果:
在带头结点的单链线性表L中第i个位置之前插入元素e;
.“链表(位置)删除算法”初始条件:
已知单链表L存在;
.操作结果:
在带头结点的单链线性表L中,删除第i个元素,并由e返回其值;
.“输出算法”初始条件:
链表L已存在;操作结果:
依次输出链表的各个结点的值;
(三)扩展实验内容(顺序表)
查前驱元素、查后继元素、顺序表合并等.
1.问题描述:
.根据给定元素的值,求出前驱元素;
.根据给定元素的值,求出后继元素;
.对已建好的两个顺序表进行合并操作,若原线性表中元素非递减有序排列,要求合并后的结果还是有序(有序合并);对于原顺序表中元素无序排列的合并只是完成A=A∪B(无序合并),要求同样的数据元素只出现一次。
.修改主程序,实现对各不同的算法调用。
2.实现要求:
.“查前驱元素算法”初始条件:
顺序线性表L已存在;操作结果:
若数据元素存在且不是第一个,则返回前驱,否则操作失败;
.“查后继元素算法”初始条件:
顺序线性表L已存在;操作结果:
若数据元素存在且不是最后一个,则返回后继,否则操作失败;
.“无序合并算法”的初始条件:
已知线性表La和Lb;
.操作结果:
将所有在线性表Lb中但不在La中的数据元素插入到La中;
.“有序合并算法”的初始条件:
已知线性表La和Lb中的数据元素按值非递减排列;操作结果:
归并La和Lb得到新的线性表Lc,Lc的数据元素也按值非递减排列;
(四)扩展实验内容(链表)
1.问题描述:
.求前驱结点是根据给定结点的值,在单链表中搜索其当前结点的后继结点值为给定的值,将当前结点返回;
.求后继结点是根据给定结点的值,在单链表中搜索其当前结点的值为给定的值,将后继结点返回;
.两个有序链表的合并是分别将两个单链表的结点依次插入到第3个单链表中,继续保持结点有序;
2.实现要求:
.“求前驱算法”初始条件:
线性表L已存在;
.操作结果:
若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱;
.“求后继算法”初始条件:
线性表L已存在;
.操作结果:
若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继;
.“两个有序链表的合并算法”初始条件:
线性表单链线性表La和Lb的元素按值非递减排列;操作结果:
归并La和Lb得到新的单链表。
三、实验环境和实验步骤
实验环境:
利用CodeBlocks10.05集成开发环境进行本实验的操作。
实验步骤――顺序表的定义与操作:
1.启动CodeBlocks10.5;
2.按“Createanewproject”,通过”file”,按“C/C++source”,选择”c”,然后GO.储存文件“D:
\c语言\顺序表.c“,
3.进行编代码。
4、编好之后,搞ctrl+shift+F9进行编译。
然后按ctrl+F10.
5.如果编译出问题,然后进行调试。
实验步骤――链表的定义与操作:
1.启动CodeBlocks10.5;
2.按“Createanewproject”,通过”file”,按“C/C++source”,选择”c”,然后GO.储存文件“D:
\c语言\单链表.c“,
3.进行编代码。
4、编好之后,搞ctrl+shift+F9进行编译。
然后按ctrl+F10.
5.如果编译出问题,然后进行调试。
四、实验分析
顺序表代码如下:
#include
#include"stdlib.h"
#include
#defineLIST_INIT_SIZE100
#defineok1
#defineERROR0
#defineOVERFLOW-1
#defineNum3
typedefintDataType;
typedefintStatus;
typedefstruct
{
DataType*elem;
intLength;
intListsize;
}SeqList;
SeqListL;
StatusInitSeqList(SeqList*L)
{
L->elem=(DataType*)malloc(LIST_INIT_SIZE*sizeof(DataType));
if(!
L->elem)
exit(OVERFLOW);
L->Length=0;
L->Listsize=LIST_INIT_SIZE;
returnok;
}
StatusInsertSeqList(SeqList*L,inti,DataTypee)
{
DataType*q,*p;
if(i<1||i>L->Length+1)
returnERROR;
else
if(L->Length>=L->Listsize)
{
printf("TheSeqListisfull!
");
returnERROR;
}
else
{
q=L->elem+i-1;
for(p=L->elem+L->Length-1;p>=q;--p)
*(p+1)=*p;
*q=e;
++L->Length;
returnok;
}
}
intDeleteSeqList(SeqList*L,inti)
{
intj;
if(i<1||i>L->Length)
{
printf("theinumberisnotexist!
");
returnERROR;
}
else
{
for(j=i-1;jLength;j++)
*(L->elem+j)=*(L->elem+j+1);
L->Length--;
returnok;
}
}
//voidSearchSeqList(SeqList*L,DataTypex)
voidSearchSeqList(SeqList*L,intx)
{
intj=0;
while(jLength&&*(L->elem+j)!
=x)
j++;
if(j>L->Length)
printf("error");
else
printf("运行结果");
printf("%d",j+1);
}
voidPrintfSeqList(SeqList*L)
{
Printf("运行结果:
");
inti;
for(i=0;iLength;i++)
printf("%d",*(L->elem+i));
}
voidLenSeqList(SeqList*L)
{
inti=0,*j;
for(j=L->elem;iLength;j++)
i++;
printf("\n元素个数为:
%d",i);
}
voidPriorSeqLement(SeqList*L,inti)
{
int*j;
if(i<1||i>L->Length)
printf("输入有误");
elseif(i==1)
printf("无前驱");
elsej=L->elem+i-2;
printf("运行结果:
");
printf("%d",*j);
}
StatusNextSeqElement(SeqList*L,inti)
{
int*j;
if(i<1||L->Length)
printf("输入有误");
elseif(i==1)
printf("无后继");
elsej=L->elem+i;
printf("运行结果:
");
printf("%d",*j);
returnok;
}
voidListSeqEmpty(SeqList*L)
{
if(L->Length==0)
printf("书序表为空");
elseprintf("顺序表非空");
}
StatusChangSeqList(SeqList*L)
{
inti,j,q;
for(i=0,j=L->Length-1;iLength/2;i++,j--)
{
q=*(L->elem+i);
*(L->elem+i)=*(L->elem+j);
*(L->elem+j)+q;
}
returnok;
}
StatusClearSeqList(SeqList*L)
{
L->Length=0;
returnok;
}
voidDestorySeqList(SeqList*L)
{
free(L);
L->Length=0;L->Listsize=0;
}
voidmain()
{
SeqList*LA=&L;
inti,e,j,x,k,m,*p,q=0;
InitSeqList(&L);
printf("输入元素:
");
for(p=LA->elem;q{
scanf("%d",p);
LA->Length++;
}
PrintfSeqList(&L);
printf("\n输入要插入元素的位置和元素:
");
scanf("%d,%d",&i,&e);
InsertSeqList(LA,i,e);PrintfSeqList(&L);
printf("\n输入要删除元素的位置:
");
scanf("%d",&j);
DeleteSeqList(&L,j);PrintfSeqList(&L);
printf("\n输入要查找的值:
");
scanf("%d",&x);
SearchSeqList(&L,x);PrintfSeqList(&L);
printf("\n输入元素求其前驱:
");
scanf("%d",&k);
PriorSeqList(&L,k);PrintfSeqList(&L);
printf("\n输入元素求其后继:
");
scanf("%d",&m);
NextSeqList(&L,m);
printf("\n求表长:
");
LenSeqList(&L);//判断表是否为空
printf("\n判断表是否为空:
\n");
ListSeqEmpty(&L);
printf("\n");
printf("逆转:
\n");
ChangSeqList(&L);
PrintfSeqList(&L);
printf("\n");
printf("置空表:
\n");
ClearSeqList(&L);
printf("\n");
printf("销毁:
");
DestorySeqList(&L);
}
单链表代码:
//List.h
#include
usingnamespacestd;
typedefintElemType;
typedefstructstudent
{
ElemTypen;
structstudent*next;
}Student,*SListLink;
classSList
{
public:
SList();//建立一个空链表**************
voidCreateSList();//建立链表**************
voidClearSList();//将链表重置为空链表**************
ElemTypeSListLength();//返回链表中的长度**************
boolSListEmpty();//判断链表是否为空链表**************
ElemTypeGetElem();//返回链表的一个元素**************
voidSortElem();//对链表排序
voidSListInsert();//插入一个元素**************
voidSListDelete();//删除一个元素**************
boolSlistDeleteSame();//删除相同的元素
voidShowSList();//显示一个链表**************
voidFileSave();//写入文件
voidFileRead();//从文件打开
voidFileDelete();//从文件删除
voidFileCheck();//查看文件内容
~SList();//销毁链表
private:
SListLinkhead;
SListLinkp;
SListLinkq;
SListLinktemp;
intslistlength;
};
SList:
:
SList()//建立一个空链表
{
head=p=q=temp=NULL;
slistlength=0;
}
voidSList:
:
CreateSList()//建立链表
{
if(head==NULL)
{
ElemTypem;
cout<<"请输入一个数字:
(0,负数表示结束输入)"<cin>>m;
if(m>0)
{
head=q=p=temp=newStudent;
q->n=m;
++slistlength;
while(m!
=0&&m>=0)
{
cout<<"请输入一个数字:
"<cin>>m;
if(m!
=0&&m>=0)
{
p=newStudent;
p->n=m;
++slistlength;
q->next=p;
q=p;
}
}
p->next=NULL;
cout<<"链表创建成功"<}
else
{
head=p=q=NULL;
}
}
else
{
cout<<"你已经创建过新链表了"<}
}
intSList:
:
SListLength()//返回链表中的长度
{
cout<<"链表中的元素个数是:
"<returnslistlength;
}
ElemTypeSList:
:
GetElem()//返回链表对应序号的一个元素
{
if(head!
=NULL)
{
ElemTypem;
cout<<"请输入要返回的数在链表中的序号"<cin>>m;
if(m>=0)
{
if(slistlength>=m)
{
intindx=1;
p=head;
while
(1)
{
if(m==indx)
{
cout<<"链表返回你查找的数:
"<n<returnhead->n;
}
p=p->next;
++indx;
if(m==indx)
{
cout<<"链表返回你查找的数:
"<n<returnp->n;
}
}
}
else
{
cout<<"序号超出链表范围"<return-1;
}
}
else
{
cout<<"不允许非法输入"<return-1;
}
}
else
{
cout<<"此链表是空链表"<return-1;
}
}
boolSList:
:
SListEmpty()//判断链表是否为空链表
{
if(head!
=NULL)
{
cout<<"此链表不是空链表"<returnfalse;
}
else
{
cout<<"此链表是空链表"<returntrue;
}
}
boolSList:
:
SlistDeleteSame()//删除链表中相同元素
{
ElemTypem;
cout<<"删除链表中相同元素的节点,请输入一个要删除的数:
"<cin>>m;
if(m>=0)
{
if(head!
=NULL)
{
returntrue;
}
else
{
cout<<"这是一个空链表"<returnfalse;
}
}
else
{
cout<<"不允许非法输入"<returnfalse;
}
}
voidSList:
:
SortElem()//对链表排序
{
if(head!
=NULL)
{
for(p=head;p!
=NULL;p=p->next)
{
temp=p;
for(q=p->next;q!
=NULL;q=q->next)
{
if(q->n>=temp->n)
{
temp=q;
}
}
if(temp!
=p)
{
ElemTypet=p->n;
p->n=temp->n;
temp->n=t;
}
}
cout<<"排序成功"<}
else
{
cout<<"此链表是空链表,不能进行此操作"<}
}
voidSList:
:
ClearSList()//将链表重置为空表
{
if(head!
=NULL)
{