单链表实验报告及程序Word文档格式.docx
《单链表实验报告及程序Word文档格式.docx》由会员分享,可在线阅读,更多相关《单链表实验报告及程序Word文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
构造一个空的线性表L。
DestroyList(&
初始条件:
线性表L已存在。
销毁线性表L。
ListEmpty(L)
操作结果:
若L为空表,则返回TRUE,否则FALSE。
ListLength(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)
若cur_e是L的元素,但不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义。
NextElem(L,cur_e,&
next_e)
若cur_e是L的元素,但不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。
ListTraverse(L,visit())
依次对L的每个元素调用函数visit()。
一旦visit()失败,则操作失败。
ClearList(&
将L重置为空表。
PutElem(L,i,&
线性表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<
string.h>
FILE*fp;
LinkListLL,p;
StatusCmp(ElemTypee1,ElemTypee2)
{
if(!
strstr(e1.num,e2.num))returnOK;
returnERROR;
}
/*
if(e1==e2)returnOK;
*/
intsavedata(LinkListL,char*file)
charstr[50];
inti;
LinkListp;
if((fp=fopen(file,"
wt"
))==NULL)
{
printf("
Cannotopenfilestrikeanykeyexit!
"
);
//getch();
exit
(1);
}
//for(i=0;
=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->
fclose(fp);
returnOK;
//intopendata(SqList&
L,char*file)
intopendata(LinkList&
charstr[50];
ElemTypee;
rt"
//getch();
while(fgets(str,50,fp)){
//fgets(str,50,fp);
//printf("
//sprintf(str,"
//sscanf(str,"
%s-%s-%d-%d"
e.no,e.name,&
(e.age),&
(e.score));
sscanf(str,"
%d"
&
e);
\n%d"
e);
\n|%8s|%9s|%10d|%11d|"
e.no,e.name,e.age,e.score);
//ListInsert_Sq(L,1,e);
ListInsert_L(L,1,e);
voidmain()
ElemTypee;
intse,cntl,i;
/*
InitList_Sq(sq);
for(inti=0;
5;
scanf("
%s%s%s%d"
e.num,e.name,e.gender,&
e.score);
ListInsert_Sq(sq,1,e);
\nNoNameGenderScore\n"
for(i=1;
=sq.length;
GetElem_Sq(sq,i,e);
\n%10s%12s%8s%5d"
e.num,e.name,e.gender,e.score);
DestroyList_Sq(sq);
/*InitList_L(LL);
for(i=0;
//scanf("
ListInsert_L(LL,1,e);
//printf("
//for(i=1;
p=LL->
i=1;
while(p){
GetElem_L(LL,i,e);
i++;
//printf("
printf("
%d"
DestroyList_L(LL);
cntl=1;
while(cntl){
//clr();
\n%30s单链表基础实验测试"
"
"
\n\n%20s=============================="
\n%20s1.单链表建立"
\n%20s2.插入"
\n%20s3.删除"
\n%20s4.查找"
\n%20s5.保存链表信息"
\n%20s6.读取链表信息"
\n%20s7.列表输出"
\n%20s0.退出"
\n请选择(0-7):
se);
cntl=1;
switch(se)
{
case0:
cntl=0;
DestroyList_L(LL);
break;
case1:
InitList_L(LL);
case2:
//scanf("
%s%d%d"
e.name,&
e.x,&
e.y);
scanf("
ListInsert_L(LL,1,e);
case3:
//scanf("
printf("
\n输入要删除数据的位置"
i);
if(ListDelete_L(LL,i,e)==OK)
printf("
else
printf("
\n没找到"
case4:
\n输入要查询数据"
LinkListp;
p=LocateElem_L(LL,e,Cmp);
if(p)
//printf("
\n%60s%8d%5d"
data.name,p->
data.x,p->
data.y);
case7:
for(i=1;
=1000;
if(GetElem_L(LL,i,e)==ERROR)
break;
e.name,e.x,e.y);
}
case5:
savedata(LL,"
e:
\\mydata.dat"
case6:
opendata(LL,"
}
3.2.单链表的建立、插入、删除等操作。
//#include<
stdlib.h>
StatusInitList_L(LinkList&
L){
//构造一个空的线性表L。
L=(LinkList)malloc(sizeof(LNode));
if(!
L)returnERROR;
//存储分配失败
L->
next=NULL;
}//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<
i-1)
{p=p->
++j;
}//寻找第i-1个结点
if(!
p||j>
i-1)
//i大于表长或者小于1
s=(LinkList)malloc(sizeof(LNode));
//生成新结点
s->
data=e;
next=p->
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;
p=L;
while(p->
next&
i-1){p=p->
}
//寻找第i个结点,并令p指向其前趋
(p->
next)||j>
//删除位置不合理
//表长减1
q=p->
next=q->
//删除并释放结点
e=q->
data;
free(q);
}//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->
//p的初值为第1个元素的存储位置
while(p&
!
(*compare)(p->
data,e))
p=p->
returnp;
}//LocateElem_L
StatusGetElem_L(LinkListL,inti,ElemType&
//L是带头结点的链表的头指针,以e返回第i个元素
p=L->
j=1;
//p指向第一个结点,j为计数器
j<
i){p=p->
//顺指针向后查找,直到p指向第i个元素
//或p为空
if(!
p||j>
i)
//第i个元素不存在
e=p->
//取得第i个元素
}
StatusDestroyList_L(LinkList&
ClearList(L);
}//DestroyList_Sq
voidClearList(LinkList&
L){
while(L->
next){
L->
next=p->
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年。