实验二线性表的链式表示和实现.docx
- 文档编号:27776454
- 上传时间:2023-07-04
- 格式:DOCX
- 页数:14
- 大小:141.22KB
实验二线性表的链式表示和实现.docx
《实验二线性表的链式表示和实现.docx》由会员分享,可在线阅读,更多相关《实验二线性表的链式表示和实现.docx(14页珍藏版)》请在冰豆网上搜索。
实验二线性表的链式表示和实现
学校代码:
10128
学号:
201220905048
《数据结构》实验报告
(
题目:
线性表的链式表示和实现
学生姓名:
孙跃
学院:
理学院
系别:
数学系
专业:
信息与计算科学
班级:
信计12-2
任课教师:
杜雅娟
二〇一四年九月
1、实验目的
理解线性结构的定义、组织形式、结构特征和类型说明以及在链式存储方式下实现的插入、删除和按值查找的算法。
2、实验内容
线性表的链式表示和实现
3、实验程序
根据给出的程序清单分别另建立4个文件:
c1.h、c2-2.h、bo2-2.cpp和main2-2.cpp,并把它们保存在同一个文件夹中。
1.预定义常量和类型
教材定义OK、ERROR等为函数结果状态代码,文件Status为其类型。
我们把这些信息放到头文件c1.h中。
c1.h还包含一些常用的,如string.h、stdio.h等。
为了操作的方便,几乎每一个程序都把C1.h包含进去,也就把这些结果状态代码和头文件包含了进去。
头文件的内容如下:
//c1.h(程序名)
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//函数结果状态代码
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
//#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行
//#defineOVERFLOW-2因为在math.h中已定义OVERFLOW的值为3,故去掉此行
typedefintStatus;//Status是函数的类型,其值是函数结果状态代码,如OK等
typedefintBoolean;//Boolean是布尔类型,其值是TRUE或FALSE
2、线性链表的单链表存储结构
//c2-2.h线性表的单链表存储结构
structLNode
{
ElemTypedata;
LNode*next;
};
typedefLNode*LinkList;//另一种定义LinkList的方法
3、单链表线性表的基本操作
//bo2-2.cpp单链表线性表(存储结构由c2-2.h定义)的基本操作(12个)
StatusInitList(LinkList&L)
{//操作结果:
构造一个空的线性表L
L=(LinkList)malloc(sizeof(LNode));//产生头结点,并使L指向此头结点
if(!
L)//存储分配失败
exit(OVERFLOW);
L->next=NULL;//指针域为空
returnOK;
}
StatusDestroyList(LinkList&L)
{//初始条件:
线性表L已存在。
操作结果:
销毁线性表L
LinkListq;
while(L)
{
q=L->next;
free(L);
L=q;
}
returnOK;
}
StatusClearList(LinkListL)//不改变L
{//初始条件:
线性表L已存在。
操作结果:
将L重置为空表
LinkListp,q;
p=L->next;//p指向第一个结点
while(p)//没到表尾
{
q=p->next;
free(p);
p=q;
}
L->next=NULL;//头结点指针域为空
returnOK;
}
StatusListEmpty(LinkListL)
{//初始条件:
线性表L已存在。
操作结果:
若L为空表,则返回TRUE,否则返回FALSE
if(L->next)//非空
returnFALSE;
else
returnTRUE;
}
intListLength(LinkListL)
{//初始条件:
线性表L已存在。
操作结果:
返回L中数据元素个数
inti=0;
LinkListp=L->next;//p指向第一个结点
while(p)//没到表尾
{
i++;
p=p->next;
}
returni;
}
StatusGetElem(LinkListL,inti,ElemType&e)//算法2.8
{//L为带头结点的单链表的头指针。
当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR
intj=1;//j为计数器
LinkListp=L->next;//p指向第一个结点
while(p&&j
{
p=p->next;
j++;
}
if(!
p||j>i)//第i个元素不存在
returnERROR;
e=p->data;//取第i个元素
returnOK;
}
intLocateElem(LinkListL,ElemTypee,Status(*compare)(ElemType,ElemType))
{//初始条件:
线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
//操作结果:
返回L中第1个与e满足关系compare()的数据元素的位序。
//若这样的数据元素不存在,则返回值为0
inti=0;
LinkListp=L->next;
while(p)
{
i++;
if(compare(p->data,e))//找到这样的数据元素
returni;
p=p->next;
}
return0;
}
StatusPriorElem(LinkListL,ElemTypecur_e,ElemType&pre_e)
{//初始条件:
线性表L已存在
//操作结果:
若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,
//返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE
LinkListq,p=L->next;//p指向第一个结点
while(p->next)//p所指结点有后继
{
q=p->next;//q为p的后继
if(q->data==cur_e)
{
pre_e=p->data;
returnOK;
}
p=q;//p向后移
}
returnINFEASIBLE;
}
StatusNextElem(LinkListL,ElemTypecur_e,ElemType&next_e)
{//初始条件:
线性表L已存在
//操作结果:
若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,
//返回OK;否则操作失败,next_e无定义,返回INFEASIBLE
LinkListp=L->next;//p指向第一个结点
while(p->next)//p所指结点有后继
{
if(p->data==cur_e)
{
next_e=p->next->data;
returnOK;
}
p=p->next;
}
returnINFEASIBLE;
}
StatusListInsert(LinkListL,inti,ElemTypee)//算法2.9。
不改变L
{//在带头结点的单链线性表L中第i个位置之前插入元素e
intj=0;
LinkListp=L,s;
while(p&&j { p=p->next; j++; } if(! p||j>i-1)//i小于1或者大于表长 returnERROR; s=(LinkList)malloc(sizeof(LNode));//生成新结点 s->data=e;//插入L中 s->next=p->next; p->next=s; returnOK; } StatusListDelete(LinkListL,inti,ElemType&e)//算法2.10。 不改变L {//在带头结点的单链线性表L中,删除第i个元素,并由e返回其值 intj=0; LinkListp=L,q; while(p->next&&j { p=p->next; j++; } if(! p->next||j>i-1)//删除位置不合理 returnERROR; q=p->next;//删除并释放结点 p->next=q->next; e=q->data; free(q); returnOK; } StatusListTraverse(LinkListL,void(*vi)(ElemType)) //vi的形参类型为ElemType,与bo2-1.cpp中相应函数的形参类型ElemType&不同 {//初始条件: 线性表L已存在 //操作结果: 依次对L的每个数据元素调用函数vi()。 一旦vi()失败,则操作失败 LinkListp=L->next; while(p) { vi(p->data); p=p->next; } printf("\n"); returnOK; } 4、检验b02-2.cpp的主程序 //main2-2.cpp检验bo2-2.cpp的主程序(与main2-1.cpp很像) #include"c1.h" typedefintElemType; #include"c2-2.h"//与main2-1.cpp不同 #include"bo2-2.cpp"//与main2-1.cpp不同 Statuscomp(ElemTypec1,ElemTypec2) {//数据元素判定函数(相等为TRUE,否则为FALSE) if(c1==c2) returnTRUE; else returnFALSE; } voidvisit(ElemTypec)//与main2-1.cpp不同 { printf("%d",c); } voidmain()//除了几个输出语句外,主程和main2-1.cpp很像 { LinkListL;//与main2-1.cpp不同 ElemTypee,e0; Statusi; intj,k; i=InitList(L); for(j=1;j<=5;j++) i=ListInsert(L,1,j); printf("在L的表头依次插入1~5后: L="); ListTraverse(L,visit);//依次对元素调用visit(),输出元素的值 i=ListEmpty(L); printf("L是否空: i=%d(1: 是0: 否)\n",i); i=ClearList(L); printf("清空L后: L="); ListTraverse(L,visit); i=ListEmpty(L); printf("L是否空: i=%d(1: 是0: 否)\n",i); for(j=1;j<=10;j++) ListInsert(L,j,j); printf("在L的表尾依次插入1~10后: L="); ListTraverse(L,visit); GetElem(L,5,e); printf("第5个元素的值为: %d\n",e); for(j=0;j<=1;j++) { k=LocateElem(L,j,comp); if(k) printf("第%d个元素的值为%d\n",k,j); else printf("没有值为%d的元素\n",j); } for(j=1;j<=2;j++)//测试头两个数据 { GetElem(L,j,e0);//把第j个数据赋给e0 i=PriorElem(L,e0,e);//求e0的前驱 if(i==INFEASIBLE) printf("元素%d无前驱\n",e0); else printf("元素%d的前驱为: %d\n",e0,e); } for(j=ListLength(L)-1;j<=ListLength(L);j++)//最后两个数据 { GetElem(L,j,e0);//把第j个数据赋给e0 i=NextElem(L,e0,e);//求e0的后继 if(i==INFEASIBLE) printf("元素%d无后继\n",e0); else printf("元素%d的后继为: %d\n",e0,e); } k=ListLength(L);//k为表长 for(j=k+1;j>=k;j--) { i=ListDelete(L,j,e);//删除第j个数据 if(i==ERROR) printf("删除第%d个数据失败\n",j); else printf("删除的元素为: %d\n",e); } printf("依次输出L的元素: "); ListTraverse(L,visit); DestroyList(L); printf("销毁L后: L=%u\n",L);} 四、实验结果(截图) 5、实验总结 通过本次实验,我们对前一阶段的所学知识进行了巩固和提高,在对上节实验课的知识进行了消化吸收的基础上,理解线性结构的定义、组织形式、结构特征和类型说明以及在链式存储方式下实现的插入、删除和按值查找的算法。 《数据结构基础》是一门纯属于设计的科目,它需用把理论变为上机调试。 刚开始学的时候确实有很多地方我们很不理解,对于我们一个初学者来说,无疑是一个具大的挑战,顺着老师的思路,我们完成自己的设计,我们可以开始运行自己的程序,在实践中检验自己所学会的知识。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 线性 链式 表示 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)