链表相关问题简单整理(有序链表提升查找效率,判断链表是否有环)


2021年1月11日16:13:47 发现1.3写错了,修正。

1. 链表

1.1 不遍历链表,删除其中一个结点

就是说只给你目标结点a,但是你没有他的前驱结点,然后要删除这个结点。

解法:先得到该节点的后续结点b,让b的内容覆盖a即可(这样a就会被当做删除了)。

1.2 求中间结点

设置快慢两个指针,快指针一次走两步,慢指针一次走一步,两个指针同时开始走,快指针遍历完链表时,慢指针所在的位置就正好是中间结点。

1.3 求倒数第k个结点

设置快慢两个指针。快指针先往前走k-1步。然后两个指针再同时开始走(这次快指针和慢指针每次都走一步),快指针遍历完链表时,慢指针所在位置正好是倒数第k个结点。

2. 链表中的环

前提:这是一个单链表,即每个结点只持有一个后续结点的地址。

2.1 如何判断链表是否有环

  • 穷举法:设定前进指针和遍历指针,前进指针每往前一步,遍历指针就从头结点开始遍历,每经过一个结点,都和前进指针所在的结点对比,如果相同,则表示这个结点出现了两次,这个链表就有环。
  • 哈希表缓存法:每经过一个点,就将这个点加入哈希表,如果重复出现,就是有环。
  • Set集合缓存法:每经过一个点,就将这个点加入Set,如果Set的大小没变化,就是有环。
  • 快慢指针法(重要):设定快指针和慢指针。快指针一次走两步,慢指针一次走一步,这样快指针先进入环,慢指针后进入环,两者一定会相遇,且相遇的时候慢指针一定在环内的第一圈。

2.3 判断环的入口

前三种方法不多说,判断有环的那一刻,就已经找到了入口,即指针当前所在的结点就是入口。

快慢指针法2:设定两个指针a和b,a置于链表头,b置于快慢指针相交处,两者均往前一步一步前行,ab指针相遇的位置就是环的入口(这部分数学证明过程比较复杂,这里只记结论)。

2.3 判断环的长度

前三种方法不多说,判断完有环后,重新再派一个指针从头开始走并计算长度,走到环的入口处,再让链表的总长度减去头到入口的长度即可。

快慢指针法3:快慢指针在相交后按照原计划继续前进(即快指针一次走2步,慢指针一次走1步),两者再次相遇时慢指针走过的长度就是环的长度(且两者一定会在同样的位置相遇)。

2.4 判断环上任意一个结点的对面结点

就是指环上距离任意一个结点a最远的结点,假设一个环结点依次是1->2->3->4->5->6,那1的对面结点就是4,2的对面结点就是5这样。

前三个方法不介绍。

快慢指针法4:在结点a上放置快慢指针,走法同之前的快慢指针。当快指针重新回到a的时候(跑一圈),慢指针正好跑了半圈,此时慢指针所在的结点就是a结点的对面结点。

2.5 判断两个链表是否有交点

设两个链表list1和list2。

让list1的尾结点指向头结点,形成一个闭环。

如果list2和list1相交,那么此刻list2中一定有一个环,如何判断有环同2.1,不多介绍。

3. 跳跃表

如果别人问你一个有序链表,如何提升他的查找效率,那么这里就要答跳跃表的知识点了。这个东西对于不知道有跳跃表的人来说基本是100%初见杀。

前提:链表有序,里面的元素按一定规则升序或者降序存放。

跳跃表的理论知识近似于二分查找,查找效率也是O(logn),他将链表分为多层,第一层就是原先的有序链表,第二层以第一层为基础每隔1个元素创建一个结点,第三层以第二层为基础每隔1个元素创建一个结点以此类推,每层的元素都指向下一层的同一个元素。
在这里插入图片描述
箭头表示持有的指针,这样一来查找就变得很方便了,我们以查找元素值为‘7’的结点为例。
在这里插入图片描述

  1. 8比7大,跳到下一层。
  2. 4比7小,前进到4。
  3. 8比7大,跳到下一层。
  4. 7为目标结点,前进到7。

参考材料

一个链表中包含环,请找出该链表的环的入口结点 - fankongkong - 博客园
https://www.cnblogs.com/fankongkong/p/7007869.html
判断链表中是否有环 ----- 有关单链表中环的问题 - dancingrain - 博客园
https://www.cnblogs.com/dancingrain/p/3405197.html
SkipList 跳表 - The time is passing - ITeye博客
https://www.iteye.com/blog/kenby-1187303

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值