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

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;
}



四. 结语


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

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在C语言中,单链表带头结点是指在链表的头部添加一个额外的结点,该结点不存储任何数据,仅用于标记链表的起始位置。引用\[3\]中的代码展示了一个带头结点的单链表的定义,其中node*表示指向一个结点的指针,linklist表示指向链表的指针。 在带头结点的单链表中,头结点的next指针指向链表的第一个实际存储数据的结点。这样做的好处是可以简化链表的操作,例如插入和删除结点时不需要特殊处理链表为空的情况。引用\[1\]和引用\[2\]中的代码展示了在带头结点的单链表中插入和删除结点的操作。 需要注意的是,在使用带头结点的单链表时,需要特别处理头结点的情况,例如在遍历链表时,通常从头结点的下一个结点开始遍历。此外,使用带头结点的单链表可以更方便地处理空链表的情况,因为头结点始终存在。 带头结点的单链表在实际应用中广泛使用,它可以更高效地进行插入、删除和查找等操作,并且可以更好地处理边界情况。 #### 引用[.reference_title] - *1* *2* *3* [带头节点的单链表(C语言版)](https://blog.csdn.net/zhu134/article/details/130632385)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值