数据结构 课件 第2章 线性表(2链表).pptx
线性表中每个元素有唯一的前驱元素和后继元素。;每个物理结点增加一个指向后继结点的指针域?单链表。
每个物理结点增加一个指向后继结点的指针域和一个指向前驱结点的指针域?双链表。;;;顺序表:需要平均移动半个表的元素。
链表:只需修改相关结点的指针域即可,这样既方便又省时。;顺序表:具有随机存取特性。
链表:不具有随机存取特性。;一般地,存储密度越大,存储空间的利用率就越高。显然,顺序表的存储密度为1(100%),而链表的存储密度小于1。;顺序表:存储密度高。
链表:存储密度相对较低。;单链表中结点类型LinkNode的声明如下:;;当访问过一个结点后,只能接着访问它的后继结点,而无法访问它的前驱结点。;插入操作:将值为x的新结点s插入到p结点之后。;a;删除操作:删除p结点之后的一个结点。;a;/55;先考虑如何整体建立单链表。;从一个空表开始,创建一个头结点。
依次读取字符数组a中的元素,生成新结点
将新结点插入到当前链表的表头上,直到结束为止。;voidList_Head(LNode*L)//头插法
{
LNode*s;intx;
L=(LNode*)malloc(sizeof(LNode));
L-next=NULL;
scanf(%d,x);
while(x!=9999){
s=(LNode*)malloc(sizeof(LNode));
s-data=x;
s-next=L-next;
L-next=s;
scanf(%d,x);
}
};注意:链表的结点顺序与逻辑次序相同。;voidList_Tail(LNode*L)//尾插法
{
intx;
L=(LNode*)malloc(sizeof(LNode));
LNode*s,*r=L;
scanf(%d,x);
while(x!=9999){
s=(LNode*)malloc(sizeof(LNode));
s-data=x;
r-next=s;
r=s;
scanf(%d,x);
}
r-next=NULL;
};;(2)销毁线性表DestroyList(L)
释放单链表L占用的内存空间。即逐一释放全部结点的空间。;while(p!=NULL) //扫描单链表L
{free(pre); //释放pre结点
pre=p; //pre、p同步后移一个结点
p=pre-next;
}
free(pre); //循环结束时,p为NULL,pre指向尾结点,释放它
};(3)判断线性表是否为空表ListEmpty(L)
若单链表L没有数据结点,则返回真,否则返回假。;(4)求线性表的长度ListLength(L)
返回单链表L中数据结点的个数。;while(p-next!=NULL)
{ n++;
p=p-next;
}
return(n); //循环结束,p指向尾结点,其序号n为结点个数
};(5)输出线性表DispList(L)
逐一扫描单链表L的每个数据结点,并显示各结点的data域值。;(6)求线性表L中位置i的数据元素GetElem(L,i,e)
在单链表L中从头开始找到第i个结点,若存在第i个数据结点,则将其data域值赋给变量e。;boolGetElem(LinkNode*L,inti,ElemTypee)
{
intj=0;
LinkNode*p=L; //p指向头结点,j置为0(即头结点的序号为0)
while(jip!=NULL)
{ j++;
p=p-next;
}
;if(p==NULL) //不存在第i个数据结点,返回false
returnfalse;
else //存在第i个数据结点,返回true
{e=p-data;
returntrue;
}
};(7)按元素值查找LocateElem(L,e)
在单链表L中从头开始找第一个值域与e相等的结点,若存在这样的结点,则返回位置,否则返回0。;;(8)插入数据元素ListInsert(L,i,e)
先在单链表L中找到第i-1个结点p,若存在这样的结点,将值为e的结点结点s插入到其后。;if(p==NULL) //未找到第i-1个结点,返回false
returnfalse;
else //找到第i-1个结点p,