【学习笔记----数据结构04-单循环链表】

循环链表

将单链表中终端结点的指针端由空指针改为指向头结点,就使整个单链表形成一个环,这种头尾相接的单链表称为单循环链表,简称循环链表(circular linked list)

它解决了一个很麻烦的问题:如何从当中一个结点出发,访问到链表的全部结点。
为了使空链表与非空链表处理一致,我们通常设一个头结点,当然这并不是说,循环链表一定要头结点。其实循环链表和单链表的主要差异就在于循环的判断条件上,原来判断p->next是否为空,现在则是p->next不等于头结点,则循环示结束。
在单链表中,我们有了头结点时,我们可以用O(1)的时间访问第一个结点,但对于要访问到最后一个结点,却需要O(n)时间,因为我们需要将单链表全部扫描一遍。有没有可能用O(1)时间由链表指针访问到最后一个结点呢?不过我们需要改造一下这个循环链表,不用头指针,而是用指向终端结点的尾指针来表示循环链表
这里写图片描述
终端结点用尾指针rear指示,则查找终端结点是O(1),而开始结点,其实就是rear->next->next。其时间很杂也为O(1);

双向链表

我们在单链表中,有了next指针,这就使得我们要查找下一结点的时间复杂度为O(1)。可是如果我们要查找的是上一结点的话,那最坏的时间复杂度就是O(n)了,因为我们每次都要从头开始遍历查找。为了克服单向性这一缺点,我们的老科学家们,设计出双向链表。
双向链表(double linkedlist): 是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。所以在双向链表中的结点都有两个指针域,一个指向直接后继,另一个指向直接前驱

/*线性表的双向链表存储结构*/
typedef struct DulNode
{
  ElemType data;
  struct DulNode   *prior;//直接前驱指针
  struct DulNode   *next; //直接后继指针
}DulNode,*DuLinkList;

由于是双向链表,那么对于链表中的某一个结点p,它的后继的前驱是谁?当然是它自己。它的前驱的后继自然也是它自己。即
p->next->prior = p =p->prior->next;
空的
这里写图片描述

非空的
这里写图片描述

双向链表是单链表中扩展出来 的结构,所以它的很多操作是和单链表相同的,比如求长度的ListLength,查找元素的GetElem,获得元素位置的LocateElem等。这些操作都只要涉及一个方向的指针即可,另一个指针多了也不能提供什么帮助。双向链表即然是比单链表多了如可以反向遍历查找等数据结构,那么也就需要付出一些小的代价:在插入和删除时,需要更改两个指针变量。
这里写图片描述

要删除结点:

这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值