单链表实验报告及程序.docx
- 文档编号:5813476
- 上传时间:2023-01-01
- 格式:DOCX
- 页数:17
- 大小:1.33MB
单链表实验报告及程序.docx
《单链表实验报告及程序.docx》由会员分享,可在线阅读,更多相关《单链表实验报告及程序.docx(17页珍藏版)》请在冰豆网上搜索。
单链表实验报告及程序
一.前言
1.1实验目的
掌握单链表的基本操作,插入、删除、查找等算法的实现。
1.2实验内容
(1)初始化单链表。
(2)在单链表中插入一个新结点。
(3)删除单链表中的某一个结点。
(4)在单链表中查找某结点并返回其位置。
(5)打印输出La中的结点元素值
1.3实验环境
1、硬件:
PC/4G内存/512G硬盘/100M/NIC
2、软件:
操作系统Windows7
MicrosoftVisualStudio6.0集成开发环境
VC++6.0
二.需求分析
2.1线性表
1、线性表概念:
n个数据元素组成的有限序列。
表示为(a1,a2,…,ai,ai+1,…,an)。
2、逻辑特征:
(1)1
(2)元素同构,且不能出现缺项。
2.2抽象数据类型线性表定义
通常采用抽象数据类型研究数据结构。
线性表查询数据类型如下:
ADTList{
数据对象:
D={ai|ai∈ElemSet,i=1,2,...,n,n≥0}
数据关系:
R1={
基本操作:
InitList(&L)
操作结果:
构造一个空的线性表L。
DestroyList(&L)
初始条件:
线性表L已存在。
操作结果:
销毁线性表L。
ListEmpty(L)
初始条件:
线性表L已存在。
操作结果:
若L为空表,则返回TRUE,否则FALSE。
ListLength(L)
初始条件:
线性表L已存在。
GetElem(L,i,&e)
初始条件:
线性表L已存在,1≤i≤ListLength(L)
操作结果:
用e返回L中第i个元素的值。
LocateElem(L,e,compare())
初始条件:
线性表L已存在,compare()是元素判定函数。
操作结果:
返回L中第i个与e满足关系compare()的元素的位序。
若这样的元素不存在,则返回值为0。
操作结果:
返回L中元素个数。
PriorElem(L,cur_e,&pre_e)
初始条件:
线性表L已存在。
操作结果:
若cur_e是L的元素,但不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。
NextElem(L,cur_e,&next_e)
初始条件:
线性表L已存在。
操作结果:
若cur_e是L的元素,但不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。
ListTraverse(L,visit())
初始条件:
线性表L已存在。
操作结果:
依次对L的每个元素调用函数visit()。
一旦visit()失败,则操作失败。
ClearList(&L)
初始条件:
线性表L已存在。
操作结果:
将L重置为空表。
PutElem(L,i,&e)
初始条件:
线性表L已存在,1≤i≤ListLength(L)
操作结果:
L中第i个元素赋值同e的值。
ListInsert(&L,i,e)
初始条件:
线性表L已存在,1≤i≤ListLength(L)+1
操作结果:
在L的第i个元素之前插入新的元素e,L的长度增1。
ListDelete(&L,i,&e)
初始条件:
线性表L已存在且非空,1≤i≤ListLength(L)
操作结果:
删除L的第i个元素,并用e返回其值,L的长度减1。
}ADTList
2.3线性表的链式表示
2.3.1.链接存储方法
链接方式存储的线性表简称为链表(LinkedList),链表的具体存储表示为:
①用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的)
②链表中结点的逻辑次序和物理次序不一定相同。
为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))
注意:
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构。
2.3.2.链表的结点结构
┌──┬──┐
│data│next│
└──┴──┘
data域--存放结点值的数据域
next域--存放结点的直接后继的地址(位置)的指针域(链域)
注意:
①链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的。
②每个结点只有一个链域的链表称为单链表(SingleLinkedList)。
2.3.3、头指针head和终端结点指针域的表示
单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。
2.3.4、单链表类型描述
typedefcharDataType;//假设结点的数据域类型为字符
typedefstructnode{ //结点类型定义
DataTypedata; //结点的数据域
structnode*next;//结点的指针域
}ListNode;
typedefListNode*LinkList;
ListNode*p;
LinkListhead;
2.3.5 指针变量和结点变量
三.编程实现
3.1主要函数代码
3.1.1.主程序
#include"linklist.h"
#include
FILE*fp;
LinkListLL,p;
StatusCmp(ElemTypee1,ElemTypee2)
{
if(!
strstr(e1.num,e2.num))returnOK;
returnERROR;
}
/*
StatusCmp(ElemTypee1,ElemTypee2)
{
if(e1==e2)returnOK;
returnERROR;
}
*/
intsavedata(LinkListL,char*file)
{
charstr[50];
inti;
LinkListp;
if((fp=fopen(file,"wt"))==NULL)
{
printf("Cannotopenfilestrikeanykeyexit!
");
//getch();
exit
(1);
}
//for(i=0;i<=L.length-1;i++){
//sprintf(str,"\n%s-%s-%d-%d",L.elem[i].no,L.elem[i].name,L.elem[i].age,L.elem[i].score);
p=L->next;
while(p)
{
//sprintf(str,"%s-%s-%d-%d\n",(p->data).no,(p->data).name,(p->data).age,(p->data).score);
sprintf(str,"%d\n",p->data);
fputs(str,fp);
//printf("%s",str);
p=p->next;
}
fclose(fp);
returnOK;
}
//intopendata(SqList&L,char*file)
intopendata(LinkList&L,char*file)
{
charstr[50];
ElemTypee;
if((fp=fopen(file,"rt"))==NULL)
{
printf("Cannotopenfilestrikeanykeyexit!
");
//getch();
exit
(1);
}
//for(i=0;i<=L.length-1;i++){
while(fgets(str,50,fp)){
//fgets(str,50,fp);
//printf("%s",str);
//sprintf(str,"\n%s-%s-%d-%d",L.elem[i].no,L.elem[i].name,L.elem[i].age,L.elem[i].score);
//sscanf(str,"%s-%s-%d-%d",e.no,e.name,&(e.age),&(e.score));
sscanf(str,"%d",&e);
printf("\n%d",e);
//printf("\n|%8s|%9s|%10d|%11d|",e.no,e.name,e.age,e.score);
//ListInsert_Sq(L,1,e);
ListInsert_L(L,1,e);
}
fclose(fp);
returnOK;
}
voidmain()
{
ElemTypee;
intse,cntl,i;
/*
InitList_Sq(sq);
for(inti=0;i<5;i++){
scanf("%s%s%s%d",e.num,e.name,e.gender,&e.score);
ListInsert_Sq(sq,1,e);
}
printf("\nNoNameGenderScore\n");
for(i=1;i<=sq.length;i++){
GetElem_Sq(sq,i,e);
printf("\n%10s%12s%8s%5d",e.num,e.name,e.gender,e.score);
}
DestroyList_Sq(sq);*/
/*InitList_L(LL);
for(i=0;i<5;i++){
//scanf("%s%s%s%d",e.num,e.name,e.gender,&e.score);
scanf("%d",&e);
ListInsert_L(LL,1,e);
}
//printf("\nNoNameGenderScore\n");
//for(i=1;i<=sq.length;i++){
p=LL->next;
i=1;
while(p){
GetElem_L(LL,i,e);
i++;
p=p->next;
//printf("\n%10s%12s%8s%5d",e.num,e.name,e.gender,e.score);
printf("%d",e);
}
DestroyList_L(LL);*/
cntl=1;
while(cntl){
//clr();
printf("\n%30s单链表基础实验测试","");
printf("\n\n%20s==============================","");
printf("\n%20s1.单链表建立","");
printf("\n%20s2.插入","");
printf("\n%20s3.删除","");
printf("\n%20s4.查找","");
printf("\n%20s5.保存链表信息","");
printf("\n%20s6.读取链表信息","");
printf("\n%20s7.列表输出","");
printf("\n%20s0.退出","");
printf("\n\n%20s==============================","");
printf("\n请选择(0-7):
");
scanf("%d",&se);
cntl=1;
switch(se)
{
case0:
cntl=0;
DestroyList_L(LL);
break;
case1:
InitList_L(LL);
break;
case2:
//scanf("%s%d%d",e.name,&e.x,&e.y);
scanf("%d",&e);
ListInsert_L(LL,1,e);
break;
case3:
//scanf("%s%d%d",e.name,&e.x,&e.y);
printf("\n输入要删除数据的位置");
scanf("%d",&i);
if(ListDelete_L(LL,i,e)==OK)
printf("%d",e);
else
printf("\n没找到");
break;
case4:
printf("\n输入要查询数据");
scanf("%d",&e);
LinkListp;
p=LocateElem_L(LL,e,Cmp);
if(p)
//printf("\n%60s%8d%5d",p->data.name,p->data.x,p->data.y);
printf("%d",e);
else
printf("\n没找到");
break;
case7:
for(i=1;i<=1000;i++){
if(GetElem_L(LL,i,e)==ERROR)
break;
//printf("\n%60s%8d%5d",e.name,e.x,e.y);
printf("%d",e);
}
break;
case5:
savedata(LL,"e:
\\mydata.dat");
break;
case6:
opendata(LL,"e:
\\mydata.dat");
break;
}
}
3.2.单链表的建立、插入、删除等操作。
//#include
#include"linklist.h"
StatusInitList_L(LinkList&L){
//构造一个空的线性表L。
L=(LinkList)malloc(sizeof(LNode));
if(!
L)returnERROR;//存储分配失败
L->next=NULL;
returnOK;
}//InitList_Sq
StatusListInsert_L(LinkListL,inti,ElemTypee){//算法2.4
//在顺序线性表L的第i个元素之前插入新的元素e,
//i的合法值为1≤i≤ListLength_Sq(L)+1
LinkListp,s;
intj;
//L为带头结点的单链表的头指针,本算法
//在链表中第i个结点之前插入新的元素e
p=L;j=0;
while(p&&j {p=p->next;++j;}//寻找第i-1个结点 if(! p||j>i-1) returnERROR;//i大于表长或者小于1 s=(LinkList)malloc(sizeof(LNode)); //生成新结点 s->data=e; s->next=p->next;p->next=s;//插入 returnOK; }//LinstInsert_L StatusListDelete_L(LinkListL,inti,ElemType&e){//算法2.5 //在顺序线性表L中删除第i个元素,并用e返回其值。 //i的合法值为1≤i≤ListLength_Sq(L)。 LinkListp,q; intj; p=L;j=0; while(p->next&&j //寻找第i个结点,并令p指向其前趋 if(! (p->next)||j>i-1) returnERROR;//删除位置不合理 //表长减1 q=p->next;p->next=q->next;//删除并释放结点 e=q->data;free(q); returnOK; }//ListDelete_Sq LinkListLocateElem_L(LinkListL,ElemTypee, Status(*compare)(ElemType,ElemType)){ //在顺序线性表L中查找第1个值与e满足compare()的元素的位序。 //若找到,则返回其在L中的位序,否则返回0。 //inti; LinkListp; //ElemType*p; //i=1;//i的初值为第1个元素的位序 p=L->next;//p的初值为第1个元素的存储位置 while(p&&! (*compare)(p->data,e)) p=p->next; returnp; }//LocateElem_L StatusGetElem_L(LinkListL,inti,ElemType&e) { //L是带头结点的链表的头指针,以e返回第i个元素 LinkListp; intj; p=L->next;j=1;//p指向第一个结点,j为计数器 while(p&&jnext;++j;} //顺指针向后查找,直到p指向第i个元素 //或p为空 if(! p||j>i) returnERROR;//第i个元素不存在 e=p->data;//取得第i个元素 returnOK; } StatusDestroyList_L(LinkList&L){ ClearList(L); returnOK; }//DestroyList_Sq voidClearList(LinkList&L){ LinkListp; while(L->next){ p=L->next; L->next=p->next; free(p); } 四.测试调试与结果分析 4.1正常测试数据及运行结果 (1)程序运行后主界面。 (2)选择1,可创建线性表。 (3)选择2,插入元素。 (4)选择3,查询元素。 (5)选择4,删除元素。 (6)选择7,列表显示 (8)选择0,退出系统。 五.收获及体会 课程实验不仅要求对课本知识有较深刻的了解,同时要求我们有较强的思维和动手能力,需要进一步了解编程思想和编程技巧。 还有就是细节决定成败,编程最需要的是严谨,在编程的时候应当字字留心,标点都要认真看,往往因为一点小小的错误而耽误很多的时间。 但也不要怕遇到错误,在实际操作过程中犯的一些错误还会有意外的收获,感觉课程设计很有意思。 在具体操作中这学期所学的数据结构的理论知识得到巩固,达到课程设计的基本目的,也发现自己的不足,在以后的上机中应更加注意。 六.参考文献 [1]杨海军马彦叶燕文编著.数据结构实验指导教程(C语言)[M].清华大学出版社,2015年。 [2]严蔚敏吴伟民.数据结构(C语言版)[M].清华大学出版社,2003年。 [3]严蔚敏吴伟民.数据结构题集(C语言版)[M].清华大学出版社,2003年。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单链表 实验 报告 程序