链表带环问题之判断链表是否带环

P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。
P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。

  

问题展示

在这里插入图片描述



一. 前言


  在链表的学习中我们知道,常见的链表如下图所示:

图1


  那带环链表又是如何呢?

  带环链表是指链表的最后一个节点的 NEXT 所指向的地址不再是“ 空指针 NULL ”,而是原链表中的一个随机节点,可能为头节点,也可能为中间节点,视情况而定。

  具体如下:
在这里插入图片描述




二. 判断链表是否带环


  在有了上面的了解后,我们将对如何判断链表是否带环进行讨论。
  很多同学可能会想到说,我们可以直接找到链表的最后一个节点,判断它的 NEXT 指向是否为 NULL 不就可以很直白的得到是否带环了吗。可话是这么说,在上图中我们可以很轻松的看出链表的尾节点是哪一个,但这只是为了方便理解而画出的图,如果换成下面这样呢?

在这里插入图片描述
  如果题目中没有明确的告知哪一个是头节点,又如何判断尾节点呢?

  显然这种方法是不可行的。

  但应对这种问题我们也不是毫无头绪,可以利用我们的“ 老朋友 ”:快慢指针 来解决问题。在这里插入图片描述
  我们让快慢指针同时指向链表的头部,之后让快指针每次在链表中走两个节点的位置,而慢指针每次走一个节点的位置,同时进行。
在这里插入图片描述
  在经历一段时间后,快指针已经在环中走了很久,而慢指针刚刚进入环,如下图所示:
在这里插入图片描述
  这时就不再是慢指针在后,快指针在前了,我们可以将其看作是快指针在慢指针的后面追赶,而我们再让它们前进一段时间后,快指针会和慢指针走到同样的位置,因为这时候他们的速度差为 1个节点(前面讲到过慢指针走一个节点,而快指针走两个节点),故不论慢指针进入环时他们相距多少距离,都一定会相遇,而当 fast == slow 时,我们就可以判断这个链表时带环得了。
在这里插入图片描述
  再说链表不带环的情况:那就是快指针走到了链表的末尾,即快指针指向了 NULL 或 快指针的NEXT指向了 NULL。




三. 代码展示


  下面是代码展示:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode ListNode, * pListNode;
bool hasCycle(struct ListNode* head)
{
    pListNode slow = head;
    pListNode fast = head;
    while (fast && fast->next)
    {
        slow = slow->next;
        fast = fast->next->next;
        if (fast == slow)
            return true;
    }
    return false;
}



四. 结语


  十分感谢您观看我的原创文章。
  本文主要用于个人学习和知识分享,学习路漫漫,如有错误,感谢指正。
  如需引用,注明地址。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值