证明链表是否为环

本文介绍了如何使用快慢指针判断链表中是否存在环,以及在不同指针步长情况下环的判定条件。快慢指针法指出,当slow走一步fast走两步时,两者一定在环中相遇,环长为偶数时相遇,奇数时可能不相遇。
摘要由CSDN通过智能技术生成

一、前言

        在数据结构中,我们会学到很多结构,例如顺序表、链表、树、环等,但是本章要重点证明的是链表中是否有环的这一问题,接下来我们一起来学习本章知识。

二、链表结构

        如下图所示,这是一副带环无头单链表。

图一:

草图:

图二:

        图一中,其结构是一个无头带环单链表,图二中,其结构是一个普通的单链表,没有环。那么要想判别有环和无环在逻辑上要如何证明呢?

三、证明

        首先对于无环的普通单链表,要想判别他的结构很简单,只需让一指针从前往后遍历,当指针为空时,就说明到了尾部,也就说明不是带环单链表。代码实现如下:

//找尾节点
void FindBack(LinkList* linklist)
{
	assert(linklist);
	while (linklist)
	{
		linklist = linklist->next;
	}

}

         但是如果对于带环单链表来说,我们就需要从中证明环的存在。

        

        对于这样一个结构来说,我们可以清晰的看到在B点处同一个节点被两个指针访问,此后进入循环,但如果想证明有环的存在,我们引入两个快慢指针,分别为fast、slow。

        开始时,让fast指针走两步,slow指针走一步,当fast达到B点进入环后,会在环内一直运动等待着slow指针,而当slow指针一旦进环,在一圈之内,fast就会追上slow,两点相遇的点视为meet。

如下图所示:

       

        一旦两个指针相遇,我们就能确定这是一个带环的单链表。        

        结论:当fast走一步,slow走两步时,两个指针一定会相遇,首先fast会先进环,slow后进环,在环中,slow走一步fast走两步,每次移动两个指针之间的距离会缩小1,直到重合。

        在图中我们把进环后fast和slow的距离设为N。

      第一次两个指针的距离为N,第二次为N-1,第三次N-2......第N次距离为0,相遇!

        以上阐述是我们按slow走一步,fast走两步所得到的结论,但是如果我们让slow走一步,fast走三步、四步、甚至更多呢,那么两个指针最终会不会相遇呢?  

        我们以slow走一步,flow走三步为例。

        设定slow进环后,两个指针的距离为N,当两个指针每走一次,它们之间的距离就会缩减2,那么在指针运行时,就会发生两种情况,其一:两个指针正好相遇,证明有环,其二:两个指针阴差阳错,错过了相遇的节点导致无法相遇。

        所以我们举例说明,当两个指针初始时之间的距离为偶数时,假如slow在1的位置,fast在3的位置,那么必然会相遇,但是如果两个指针初始时之间的距离为奇数时,一旦两个指针错过,那么就有可能永远追不上了。

结论得出:

fastslow是否一定会相遇
走两步走一步一定会相遇

        假设环的长度为C,slow和fast的距离变成C-1,当C-1为偶数时,那么下一轮可以追上,如果C-1为奇数时那么就永远追不上了。

  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值