数据结构中链表及常见操作Word文档格式.docx
- 文档编号:21685247
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:14
- 大小:24.04KB
数据结构中链表及常见操作Word文档格式.docx
《数据结构中链表及常见操作Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构中链表及常见操作Word文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
双向链表可以从任何一个节点访问前一个节点,当然也可以访问后一个节点,以至整个链表。
一般是在需要大批量的另外储存数据在链表中的位置的时候用。
2.3循环链表
在一个循环链表中,首节点和末节点被连接在一起。
这种方式在单向和双向链表中皆可实现。
要转换一个循环链表,你开始于任意一个节点然后沿着列表的任一方向直到返回开始的节点。
指向整个列表的指针可以被称作访问指针。
循环链表中第一个节点之前就是最后一个节点,反之亦然。
3链表常见用途
常用于组织删除、检索较少,而添加、遍历较多的数据。
4链表和数组的区别
数组在内存中是逐个存放的,也就是说倘若数组的第一个元素在地址A,则数组第二个元素就在地址A+1。
而链表则不是,链表每个节点没有相对固定的位置关系。
某个节点在地址A其后的节点不一定是A+1,而在内存的其他空闲区域,呈现一种随机的状态。
数组一旦显式的被申明后,其大小就固定了,不能动态进行扩充。
而链表则可以,可以动态生成节点并且添加到已有的链表中。
链表灵活,但是空间和时间额外耗费较大;
数组大小固定,元素位置固定,但是操作不灵活,且容易浪费空间,但是时间耗费较小,尤其是元素变化不大的时候效率很高。
双向链表比单向的更灵活,但是空间耗费也更大。
从内存存储来看,(静态)数组从栈中分配空间,对于程序员方便快速,但是自由度小;
链表从堆中分配空间,自由度大但是申请管理比较麻烦。
附录:
(链表的部分常见操作)
1单向链表
/*线性表的单链表存储结构*/
typedefstructLNode{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
/*带有头结点的单链表的基本操作(12个)*/
voidInitList(LinkList*L)
{/*操作结果:
构造一个空的线性表L*/
*L=(LinkList)malloc(sizeof(structLNode));
/*产生头结点,并使L指向此头结点*/
if(!
*L)/*存储分配失败*/
exit(OVERFLOW);
(*L)->
next=NULL;
/*指针域为空*/
}
voidDestroyList(LinkList*L)
{/*初始條件:
线性表L已存在。
操作结果:
销毁线性表L*/
LinkListq;
while(*L)
{q=(*L)->
next;
free(*L);
*L=q;
}
voidClearList(LinkListL)/*不改变L*/
{/*初始条件:
将L重置为空表*/
LinkListp,q;
p=L->
/*p指向第一个结点*/
while(p)/*没到表尾*/
{q=p->
free(p);
p=q;
L->
/*头结点指针域为空*/
StatusListEmpty(LinkListL)
若L为空表,则返回TRUE,否则返回FALSE*/
returnL->
next==NULL;
intListLength(LinkListL)
返回L中数据元素个数*/
inti=0;
LinkListp=L->
{
i++;
p=p->
returni;
StatusGetElem(LinkListL,inti,ElemType*e)
{/*L为带头结点的单链表的头指针。
当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR*/
intj=1;
/*j为计数器*/
while(p&
&
j<
i)/*顺指针向后查找,直到p指向第i个元素或p为空*/
j++;
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*/
while(p)
if(compare(p->
data,e))/*找到这样的数据元素*/
return0;
StatusPriorElem(LinkListL,ElemTypecur_e,ElemType*pre_e)
线性表L已存在*/
若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,*/
/*返回OK;
否则操作失败,pre_e无定义,返回INFEASIBLE*/
LinkListq,p=L->
while(p->
next)/*p所指结点有后继*/
q=p->
/*q为p的后继*/
if(q->
data==cur_e)
*pre_e=p->
/*p向后移*/
returnINFEASIBLE;
StatusNextElem(LinkListL,ElemTypecur_e,ElemType*next_e)
线性表L已存在*/
/*操作结果:
若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,*/
/*返回OK;
否则操作失败,next_e无定义,返回INFEASIBLE*/
if(p->
*next_e=p->
next->
StatusListInsert(LinkListL,inti,ElemTypee)
{/*在带头结点的单链线性表L中第i个位置之前插入元素e*/
intj=0;
LinkListp=L,s;
i-1)/*寻找第i-1个结点*/
i-1)/*i小于1或者大于表长*/
s=(LinkList)malloc(sizeof(structLNode));
/*生成新结点*/
s->
data=e;
/*插入L中*/
next=p->
p->
next=s;
StatusListDelete(LinkListL,inti,ElemType*e)
{/*在带头结点的单链线性表L中,删除第i个元素,并由e返回其值*/
LinkListp=L,q;
next&
j<
i-1)/*寻找第i个结点,并令p指向其前驱*/
p->
next||j>
i-1)/*删除位置不合理*/
/*删除并释放结点*/
next=q->
*e=q->
free(q);
voidListTraverse(LinkListL,void(*vi)(ElemType))
/*vi的形参类型为ElemType,与bo2-1.c中相应函数的形参类型ElemType&
不同*/
依次对L的每个数据元素调用函数vi()*/
vi(p->
data);
printf("
\n"
);
2双向链表
/*线性表的双向链表存储结构*/
typedefstructDuLNode
{
structDuLNode*prior,*next;
}DuLNode,*DuLinkList;
/*带头结点的双向循环链表的基本操作*/
voidInitList(DuLinkList*L)
{/*产生空的双向循环链表L*/
*L=(DuLinkList)malloc(sizeof(DuLNode));
if(*L)
next=(*L)->
prior=*L;
else
voidDestroyList(DuLinkList*L)
销毁双向循环链表L*/
DuLinkListq,p=(*L)->
while(p!
=*L)/*p没到表头*/
*L=NULL;
voidClearList(DuLinkListL)/*不改变L*/
L已存在。
DuLinkListq,p=L->
=L)/*p没到表头*/
next=L->
prior=L;
/*头结点的两个指针域均指向自身*/
StatusListEmpty(DuLinkListL)
if(L->
next==L&
L->
prior==L)
returnTRUE;
returnFALSE;
intListLength(DuLinkListL)
DuLinkListp=L->
StatusGetElem(DuLinkListL,inti,ElemType*e)
{/*当第i个元素存在时,其值赋给e并返回OK,否则返回ERROR*/
=L&
jnext;
if(p==L||j>
intLocateElem(DuLinkListL,ElemTypee,Status(*compare)(ElemType,ElemType))
L已存在,compare()是数据元素判定函数*/
返回L中第1个与e满足关系compare()的数据元素的位序。
/*p指向第1个元素*/
=L)
StatusPriorElem(DuLinkListL,ElemTypecur_e,ElemType*pre_e)
若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,*/
/*否则操作失败,pre_e无定义*/
/*p指向第2个元素*/
prior->
StatusNextElem(DuLinkListL,ElemTypecur_e,ElemType*next_e)
/*否则操作失败,next_e无定义*/
DuLinkListGetElemP(DuLinkListL,inti)/*另加*/
{/*在双向链表L中返回第i个元素的地址。
i为0,返回头结点的地址。
若第i个元素不存在,*/
/*返回NULL*/
intj;
DuLinkListp=L;
/*p指向头结点*/
if(i<
0||i>
ListLength(L))/*i值不合法*/
returnNULL;
for(j=1;
=i;
j++)
returnp;
StatusListInsert(DuLinkListL,inti,ElemTypee)
{/*在带头结点的双链循环线性表L中第i个位置之前插入元素e,i的合法值为1≤i≤表长+1*/
/*改进算法2.18,否则无法在第表长+1个结点之前插入元素*/
DuLinkListp,s;
1||i>
ListLength(L)+1)/*i值不合法*/
p=GetElemP(L,i-1);
/*在L中确定第i个元素前驱的位置指针p*/
p)/*p=NULL,即第i个元素的前驱不存在(设头结点为第1个元素的前驱)*/
s=(DuLinkList)malloc(sizeof(DuLNode));
s)
returnOVERFLOW;
prior=p;
/*在第i-1个元素之后插入*/
prior=s;
StatusListDelete(DuLinkListL,inti,ElemType*e)
{/*删除带头结点的双链循环线性表L的第i个元素,i的合法值为1≤i≤表长*/
DuLinkListp;
1)/*i值不合法*/
p=GetElemP(L,i);
/*在L中确定第i个元素的位置指针p*/
p)/*p=NULL,即第i个元素不存在*/
//?
?
没有考虑链表头?
链表尾?
prior=p->
prior;
voidListTraverse(DuLinkListL,void(*visit)(ElemType))
{/*由双链循环线性表L的头结点出发,正序对每个数据元素调用函数visit()*/
visit(p->
voidListTraverseBack(DuLinkListL,void(*visit)(ElemType))
{/*由双链循环线性表L的头结点出发,逆序对每个数据元素调用函数visit()。
另加*/
/*p指向尾结点*/
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 中链表 常见 操作