【数据结构】线性表3——线性表的链式表示和实现(循环链表和双向链表)


循环链表

  • 定义:循环链表是一种头尾相接的链表(即:表中最后一个结点的指针域指向头结点,整个链表形成一个环)。

在这里插入图片描述

  • 优点:从表中任一结点出发均可找到表中其他结点。
  • 注意:
    由于循环链表中没有NULL指针,故涉及遍历操作时,其终止条件就不再像非循环链表那样判断p或p->next 是否为空,而是判断它们是否等于头指针。
  • 循环条件:
//单链表
p!=NULL
p->next!=NULL

//单循环链表
p!=L
p->next!=L
  • 头指针表示单循环链表

在这里插入图片描述
表的操作常常在表的首位位置上进行

  • 尾指针表示单循环链表

在这里插入图片描述

  • 带尾指针循环链表的合并

在这里插入图片描述

//假设Ta,Tb都是非空的单循环链表
LinkList Connect(LinkList Ta,LinkList Tb){
	p=Ta->next;  //p存表头结点
	Ta->next=Tb->next->next;  //Tb表头连结点Ta表尾  
	delete Tb->next;  //释放Tb表头结点
	Tb->next=p;  //修改指针
	return Tb;
}

时间复杂度:O(1)

为什么要讨论双向链表:
单链表的结点:
① 有指示后继的指针域,找后继结点方便;即查找某结点的后继结点的执行时间为a(1)。
② 无指示前驱的指针域,找前驱结点难:从表头出发查找。即:查找某结点的前驱结点的执行时间为a(n)。
可用双向链表来克服单链表的这种缺点。

双向链表

  • 定义:双向链表在单链表的每个结点里再增加一个指向其直接前驱的指针域prior ,这样链表中就形成了有两个方向不同的链,故称为双向链表。
    在这里插入图片描述

  • 双向链表的结构定义:

typedef struct DuLNode{
	Elemtype data;
	struct DuLNode *prior,*next;
}DuLNode,*DuLinkList;

在这里插入图片描述

双向循环链表

  • 描述:双向循环链表和单链的循环表类似,双向链表也可以有循环表。 让头结点的前驱指针指向链表的最后一个结点;
    让最后一个结点的后继指针指向头结点。

在这里插入图片描述

  • 双向链表结构的对称性
    在双向链表中有些操作(如: (ListLength、GetElem等),因仅涉及一个方向的指针,故它们的算法与线性链表的相同。但在插入、删除时,则需同时修改两个方向上的指针,两者的操作的时间复杂度均为O(n)。

在这里插入图片描述

p->prior->next=p=p->next->prior

双向链表基本操作的实现

在双向链表中有些操作(如: (ListLength、GetElem等),因仅涉及一个方向的指针,故它们的算法与线性链表的相同。但在插入、删除时,则需同时修改两个方向上的指针,所以有所不同。

1、双向链表的插入
在这里插入图片描述

void ListInsert_DuL(DuLinkList &L,int i,ElemType e){
	if(!(p=GetElemP_DuL(L,i)))
		return error;
	s=new DuLDode;
	s->data=e;
	s->prior=p->prior;//a结点成为x结点的前驱结点
	p->prior->next=s;//a结点成为x结点的后继结点
	s->next=p;//x结点成为b结点的前驱结点
	p->prior=s;//x结点成为b结点的后继结点
	return ok;
}  //ListInsert_DuL

时间复杂度:O(n)

2、双向链表的删除
在这里插入图片描述

void ListDelete_DuL(DuLink &L,int i,ElemType &e){
	if(!(p=GetElemP_DuL(L,i)))
		return error;
	e=p->data;
	p->prior->next=p->next;
	p->next->prior=p->prior;
	free(p);
	return ok;
}  //ListDelete_DuL

时间复杂度:O(n)

ending~~~

有什么问题欢迎留言噢

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
线性表是一种常见的数据结构,用于存储相同类型的数据元素。实现线性表的两种存储结构分别是顺序存储结构和链式存储结构。 顺序存储结构(seqlist)是将数据元素存储在一块连续的内存空间中。我们可以使用数组来实现顺序存储结构。数组提供了随机访问的能力,通过下标可以直接访问到对应位置的元素。顺序存储结构的特点是插入和删除操作不方便,需要移动大量的元素。同时,顺序存储结构的大小是固定的,无法灵活地改变大小。 链式存储结构(linklist)使用指针将数据元素链接在一起。每个元素中包含一个数据域和一个指针域,指针域指向下一个元素。链式存储结构的特点是插入和删除操作方便,不需要移动其他元素。同时,链式存储结构的大小可以动态调整,可以灵活地增加或删除元素。但是链式存储结构的访问速度相对较慢,需要通过指针逐个遍历元素。 为了实现线性表的顺序存储结构,我们可以声明一个固定大小的数组,并使用一个整型变量来记录有效元素的个数。然后通过下标来访问元素,插入和删除操作需要进行元素的移动。 为了实现线性表链式存储结构,我们声明一个结构体来表示一个节点,节点中包含一个数据域和一个指针域。然后通过指针来链接各个节点,形成链表链表的头节点可以通过一个指针来访问,通过修改指针可以进行插入和删除操作。 综上所述,线性表的顺序存储结构和链式存储结构分别具有不同的特点和适用场景。视具体的需求和应用场景来选择使用哪种存储结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白白卡路里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值