链表是否有环

判断两个链表是否相交 参考:http://blog.chinaunix.net/uid-20754793-id-177773.html 判断两个链表是否相交:(假设两个链表都没有环)有以下三种方法: 1、判断第一个链表的每个节点是否在第二个链表中 2、把第二个链表连接到第一个后面,判断得到的链表是否有环,有环则相交 3、先遍历第一个链表,记住最后一个节点,再遍历第二个链表,得到最后一个节点时和第一个链表 阅读详情

链表是否有环

判断链表是否有环以及环的入口点
有几种解法:
1. 遍历链表,将已经遍历过的节点放在一个hash表中,如果一个节点已经存在hash表中,说明有环。时间:O(n) 空间:O(n)


2. 反转链表 时间O(n),空间O(1),使用三个指针


3. 快慢指针。 时间O(n), 空间O(1),使用两个指针


参考:
http://kb.cnblogs.com/page/52054/
http://www.cnblogs.com/shawn-zhou/archive/2008/11/26/1341307.html
http://kb.cnblogs.com/page/52054/
http://keep.javaeye.com/blog/293454

 

【摘要】有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。1、如何判断一个链表是不是这类链表?2、如果链表为存在环,如果找到环的入口点?扩展:判断两个单链表是否相交,如果相交,给出相交的第一个点。
有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。

问题:

1、如何判断一个链表是不是这类链表?
2、如果链表为存在环,如果找到环的入口点?

解答:

一、判断链表是否存在环,办法为:

设置两个指针(fast, slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇。(当然,fast先行头到尾部为NULL,则为无环链表)程序如下:

bool IsExitsLoop(slist * head)
{
slist * slow = head , * fast = head;

while ( fast && fast -> next )
{
slow = slow -> next;
fast = fast -> next -> next;
if ( slow == fast ) break ;
}

return ! (fast == NULL || fast -> next == NULL);
}

二、找到环的入口点

当fast若与slow相遇时,slow肯定没有走遍历完链表,而fast已经在环内循环了n圈(1<=n)。假设slow走了s步,则 fast走了2s步(fast步数还等于s 加上在环上多转的n圈),设环长为r,则:

2s = s + nr
s= nr

设整个链表长L,入口环与相遇点距离为x,起点到环入口点的距离为a。
a + x = nr
a + x = (n - 1)r +r = (n-1)r + L - a
a = (n-1)r + (L - a - x)

(L - a - x)为相遇点到环入口点的距离,由此可知,从链表头到环入口点等于(n-1)循环内环+相遇点到环入口点,于是我们从链表头、与相遇点分别设一个指针,每次各走一步,两个指针必定相遇,且相遇第一点为环入口点。

程序描述如下:

slist * FindLoopPort(slist * head)
{
slist * slow = head, * fast = head;

while ( fast && fast -> next )
{
slow = slow -> next;
fast = fast -> next -> next;
if ( slow == fast ) break ;
}

if (fast == NULL || fast -> next == NULL)
return NULL;

slow = head;
while (slow != fast)
{
slow = slow -> next;
fast = fast -> next;
}

return slow;
}

 

附一种易于理解的解释:

 

一种O(n)的办法就是(搞两个指针,一个每次递增一步,一个每次递增两步,如果有环的话两者必然重合,反之亦然):
关于这个解法最形象的比喻就是在操场当中跑步,速度快的会把速度慢的扣圈

可以证明,p2追赶上p1的时候,p1一定还没有走完一遍环路,p2也不会跨越p1多圈才追上

我们可以从p2和p1的位置差距来证明,p2一定会赶上p1但是不会跳过p1的

因为p2每次走2步,而p1走一步,所以他们之间的差距是一步一步的缩小,4,3,2,1,0 到0的时候就重合了

根据这个方式,可以证明,p2每次走三步以上,并不总能加快检测的速度,反而有可能判别不出有环

既然能够判断出是否是有环路,那改如何找到这个环路的入口呢?

解法如下: 当p2按照每次2步,p1每次一步的方式走,发现p2和p1重合,确定了单向链表有环路了

接下来,让p2回到链表的头部,重新走,每次步长不是走2了,而是走1,那么当p1和p2再次相遇的时候,就是环路的入口了。

这点可以证明的:

在p2和p1第一次相遇的时候,假定p1走了n步骤,环路的入口是在p步的时候经过的,那么有

p1走的路径: p+c = n; c为p1和p2相交点,距离环路入口的距离

p2走的路径: p+c+k*L = 2*n; L为环路的周长,k是整数

显然,如果从p+c点开始,p1再走n步骤的话,还可以回到p+c这个点

同时p2从头开始走的话,经过n步,也会达到p+c这点

显然在这个步骤当中p1和p2只有前p步骤走的路径不同,所以当p1和p2再次重合的时候,必然是在链表的环路入口点上。

 

 

 

扩展问题:

判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)。

比较好的方法有两个:

一、将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的依赖环入口即为相交的第一个点。

二、如果两个链表相交,那个两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。

这时我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。

如何判断链表中是否有环 今天面试被问住了,很惭愧啊,回来上网查了一下思路。自己写了点程序。 1.如何判断是否有环?如果有两个头结点指针,一个走的快,一个走的慢,那么若干步以后,快的指针总会超过慢的指针一圈。 2.如何计算环的长度?第一次相遇(超一圈)时开始计数,第二次相遇时停止计数。 3.如何判断环的入口点:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接 阅读详情

相关推荐

判断链表是否有环,判断环的入口

pre 面试中遇到过,知道解法,但是细节不是很了解,这里重新整理一下思路,通知给出关键部分的理由和证明 问题1:判断链表是否有环 问题分析 首先考虑环出现之后链表的特征,从头开始的链表遍历无法结束,也就是不存在尾节点 这时候第一个想法,一遍遍历链表,直至出现null 或者下一个元素是之前出现过的元素,那么这样时间复杂度为O(n),空间复杂度为O(n)[这里需要缓存之前节点的访问的...

月光轩辕的专栏 3953

各种方式巧判断链表相交

判断两个链表是否相交 0 问题 判断两个单链表是否相交,(拓展一下就是,如果相交,那么节点在哪?) 1 开场白 因为是单链表,可以看出每个节点只有一个后继节点,所以只存在两个链汇成一个链,不会存在两个链在一点交织,然后分散成两个链,所以问题的求解就与习题4-4,寻找相同后缀的问题基本类似了 2 算法介绍 2.0 数据结构 typedef struct LNode{ int data; LNode *next; }*LinkList, LNode; //且具有头结点! 2.1 利用has

qq_43148207的博客 541

HPE磁盘阵列管理04——MSA事件

本文介绍了HPE MSA存储系统的事件处理机制,重点分析了常见磁盘故障事件及其解决方案。文章首先定义了MSA事件的五个严重级别(严重、错误、警告、信息和解决),然后详细列举了多个典型事件案例(如事件1、3、6、8、172等),包括每种事件的触发条件、对系统的影响以及具体修复步骤。针对磁盘故障场景,文章提供了更换磁盘、重建磁盘组、取消隔离等操作建议,并强调应及时配置备用磁盘以降低数据风险。最后指出更详细的事件说明可参考《MSA事件描述参考指南》,并提供了HPE官方手册下载链接。全文为技术人员处理MSA存储故障

istrangeboy&begin zero的博客 1118

判断单链表是否存在环,判断两个链表是否相交问题详解(转载)

【摘要】有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。1、如何判断一个链表是不是这类链表?2、如果链表为存在环,如果找到环的入口点?扩展:判断两个单链表是否相交,如果相交,给出相交的第一个点。 有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。 问题: 1、如...

zone 332

FPGA之全数字锁相环(DPLL)

1. 数字锁相环的基本原理和组成 1.1 锁相环(PLL)的简介 锁相环最开始并不是用在数字电路中,而是模拟短路中。对于模拟电路中的锁相环,大家可以参考这篇文章稍微看一下,数字和模拟只是实现的方法不同,但是原理、步骤还是共同的。关于模拟PLL。可以参考一片文章: http://www.sohu.com/a/190569594_464086 首先在学习数字锁相环之前,我们应该先了解什么是锁相环?锁相...

DBLLLLLLLL的博客 5万+

基于深度学习的高精度牙齿健康检测识别系统(PyTorch+Pyside6+YOLOv5模型)

近年来,机器学习和深度学习取得了较大的发展,深度学习方法在检测精度和速度方面与传统方法相比表现出更良好的性能。YOLOv5是单阶段目标检测算法YOLO的第五代,根据实验得出结论,其在速度与准确性能方面都有了明显提升,开源的代码可见https://github.com/ultralytics/yolov5。因此本博文利用YOLOv5检测算法实现一种高精度家禽猪识别检测模型,再搭配上Pyside6库写出界面系统,完成目标检测识别页面的开发。

sc1434404661的博客 5799

判断链表相交

LeetCode-链表相交

Lion__king的博客 911

Veritas NetBackup 10.1 Windows安装指南:从账户配置到完整部署

本文详细介绍了Veritas NetBackup 10.1在Windows系统上的完整安装流程,从账户配置到部署验证。重点讲解了创建专用服务账户、安装组件选择、许可证输入等关键步骤,并提供了常见问题排查和进阶配置建议,帮助用户顺利完成企业级备份解决方案的部署。

weixin_26765287的博客 453

如何判断单向链表中是否有环

例子:有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环。如图所示: 问题一:如何判断一个链表是不是这类链表? 问题二:如果链表为存在环,如何找到环的入口点? 问题三:如果链表为存在环,环的长度又是多少? 问题一 方法:各种博客论坛网上提供了各种方法来判断链表是否存在环,总结起来就是两类:1、穷举遍历;2、快慢指...

4110

emwin与Modbus通信结合:项目实例

通过实际项目讲解emwin界面设计与Modbus通信协议的融合应用,深入剖析数据交互流程。掌握emwin在工业控制场景中的实用技巧,提升系统人机交互与稳定通信能力。

weixin_34618526的博客 483

Codex 100个真实案例 - 用AI生成Blender 3D建模脚本(建模师要失业了?)

本案例将展示如何用 Codex 生成 Blender Python API(bpy)脚本,自动创建完整的 3D 模型。我们将从基础几何体开始,逐步实现布尔运算、材质设置、光照配置,最终完成一张精美桌子的 3D 建模——包括桌面、桌腿、倒角、木纹材质。还会实现参数化批量生成不同风格的桌子、渲染输出 PNG 图片、以及 360 度旋转动画。全程用自然语言驱动 Codex,让建模从"点鼠标"变成"说人话"!

yueyeguzhuo的专栏 630

判断链表中是否有环

判断链表是否有环

zxjiaya的博客 952

基于应用谱减法进行语音去噪的算法

在上述代码中首先通过读取语音信号和噪声信号,将两个信号都转换为频域信号,然后计算出语音信号在各频率下的功率谱和噪声信号在各频率下的功率谱,并基于此计算信噪比,接着根据信噪比计算出阈值,并将低于阈值的能量对应的频段进行清零操作,最终实现去噪处理,最后将处理后的信号转换回时域信号。该算法采用谱减法进行降噪处理,能有效地去除语音信号中的噪声,但是在实际应用中,该方法也存在一些问题,如会对语音信号的高频部分产生影响,所以需要在应用过程中进行适当的调整。

weixin_50547796的博客 192

判断一条链表上是否存在环

判断一条链表上是否存在环 方法一、简单粗暴的方法,两套循环遍历链表,查看是否存在相同的节点,如果有,则存在环;没有,则不存在环,时间复杂度O(n^2),面试官肯定不愿意看到这种解决方式。 是否存在时间复杂度为O(n)的算法求解该问题呢?有的有效的方法(内存开销更少的方法)是由Floyd提出的,所以该方法称为Floyd环判定算法。 方法二、该方法使用两个在链表中具有不同移动速度的指针。一旦它们...

凌凌小博客 2万+

【ArcGIS风暴】Win10操作系统ArcGIS许可License无法启动的解决方法汇总(绝对成功!)

文章目录1. 关闭Windows Defender2. 关闭系统防火墙3. 删除迈克菲(McAfee)杀毒软件4. 在系统服务中启动 在安装ArcGIS软件时,最重要的一步是许可服务的正常启动,通常,由于各种各样的原因,ArcGIS许可管理器License Manager十有八九会无法启动,点N多次都没反应,如果许可服务不能如愿启动的话,即使Desktop安装成功,也是无法打开的。本文汇总了Win10操作系统之上ArcGIS安装过程中可能会导致服务无法启动的原因及解决办法。 ArcGIS安装参考教程:

智慧空间实验室 2万+

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

python判断链表是否有环_判断链表是否有环

判断一个单向链表是否有环。(指向表头结点的指针为head)方法一:(1)用两个指针p1和p2分别指向表头结点,即p1=p2=head(2)p1和p2分别采用1和2作为步长遍历该链表。(注意,p2应该检查当前结点的下一个结点是否为NULL)(3)如果p1或者p2遇到了NULL,则证明该链表没有环;若p1和p2在某时刻指向同一结点,则说明该链表有环。点击(此处)折叠或打开bool I***itsLoo...

weixin_32652003的博客 1777

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

数据结构---如何判定链表是否有环_如何判断链表是否有环

可以对第一 个链表的节点地址进行hash排序,建立hash表,然后针对第二个链表的每个节点的地址查询hash表,如果它在hash表中出现,则说明两个链表有共 同的结点。对于相交的第一个结点,则可求出两个链表的长度,然后用长的减去短的得到一个差值 K,然后让长的链表先遍历K个结点,然后两个链表再开始比较。例如链表A->B->C->D->B->C->D,两个指针最初都指向节点A,进入第一轮循环,指针1移动到了节点B,指针2移动到了C。第二轮循环,指针1移动到了节点C,指针2移动到了节点B。

2201_75604580的博客 1109

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

如何判断链表是否有环_【日拱一卒】链表——判断链表是否有环

需求判定一个链表是否有环这张图不存在环,头结点是1,尾结点是5。这张图中,节点2-3-4-5-2就构成了环。思路思路1 ——快慢指针顾名思义,一个快指针,一个慢指针。如果不包括环,快慢指针同向行驶,根据小学经典数学题,他们永远无法相遇,而且差距只会越来越大。如果链表有环,意味着快慢指针都会调头,好比操场跑步,第一圈快指针在慢指针前面,但是后面快指针迟早会追上慢指针。所以可以借助这个思想,...

weixin_39894473的博客 83

python链表——判断链表是否有环

输入:1->2->3->4->5->6->7->3(3为链表中的第三个节点) 输出:True 思路: 快慢法来求解,slow走一步,fast走2步,从head出发,如果带环的话,必定相遇。 代码 # 判断链表是否有环 def is_Loop(head): if head is None or head.next is None: ...

chenlibao0823的博客 1160

链表--如何检测一个链表是否有环及如何找到环的入口点

如何检测一个链表是否有环 有环的链表: 有环的链表是指链表有环路,例如A-&amp;gt;B-&amp;gt;C-&amp;gt;D-&amp;gt;E-&amp;gt;F-&amp;gt;B,遍历的时候B-&amp;gt;C-&amp;gt;D-&amp;gt;E-&amp;gt;F-&amp;gt;B会形成环路一直循环。 思路: 设置一个快指针fast,一个慢指针slow,二者初始都指向链表头,fas

yangruxi的博客 1万+

判断链表是否有环及两链表是否相交

单向链表是最常用的数据结构之一,因此总结其常见的问题及其解决方案是很有意义的。 问题1:如何判断一个单向链表是否有环?如果有,如何找到其入口节点的指针?               算法思想:用两个指针p1,p2同时指向链表的头部,p1一次移动一步,p2一次移动两步,如果最终p1

扬风踏浪 7005

如何判断链表是否有环_谈一谈如何判断链表有环

最近看了程序员小灰的一篇文章漫画算法:如何判断链表有环?, 问题描述如下:有一个单向链表,链表当中有可能出现“环”,就像下图这样。如何用程序判断出这个链表是有环链表?如下图所示一个带环的单向链表.文章中的方法三给出了简洁的算法:方法三:首先创建两个指针1和2(在java里就是两个对象引用),同时指向这个链表的头节点。然后开始一个大循环,在循环体中,让指针1每次向下移动一个节点,让指针2每次向下移动...

weixin_39809793的博客 388
上一篇: 编程之美程序改错
下一篇: 苹果二叉树
mingming_bupt
博客等级 码龄17年 26粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值