有一个单链表,其中可能有一个环,也就是某个节点的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;
}
三、判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)。
比较好的方法有两个:
一、将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的依赖环入口即为相交的第一个点。
二、如果两个链表相交,那个两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。
这时我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。

转载于:https://blog.51cto.com/sbxxs/218781

判断链表是否存在环(及其延伸)相关推荐

  1. 快慢指针判断链表是否有环

    链表中很经常会出现的一个问题,判断链表是否有环,标准答案也已经烂熟于心,设置快慢指针,快指针每次走2步,慢指针每次走1步,如果两个指针可以相遇的话,证明链表有环,反之无环. 我有时候就犯嘀咕,它俩一定 ...

  2. 【刷算法】判断链表是否有环以及返回入环节点

    题目描述 判断一个单链表是否有环,有环则返回入环节点,否则返回null 1->2->3->4->5->6↑ ↓8<-7 复制代码 例如上面这个链表就有环,入环节点是 ...

  3. 双指针算法之快慢指针(一):力扣【判断链表是否有环】leetcode-141、142

    一.简介:什么是快慢指针? 快慢指针,顾名思义,无非就是设置一个快指针,一个慢指针,初始化的时候,快指针和慢指针都指向链表的头结点,前进的时候一个在前一个在后,结合起来可以十分巧妙的解决链表中的一些问 ...

  4. 剑指offer之判断链表是否包含环

    1 问题 判断链表是否包含环 2 思路 2个指针,一个指针走一步,一个指针走2步,如果相遇则有,反之无. 3 代码实现 #include <stdio.h> #include <st ...

  5. 数据结构:单链表操作之如何判断链表是否带环及相关操作

    //判断链表是否有环 int HasCircle(Node* pHead) { Node* low=pHead; Node* fast=pHead;     while(fast != NULL &a ...

  6. 面试题:判断链表是否存在环

    题目:判断链表是否存在环 思路:定义快慢指针,如果两个指针相遇则一定存在环. 1 public bool IsCircled(Node First) 2 { 3 if (First == null | ...

  7. 数据结构---判断链表是否有环

    判断链表是否有环 判断链表是否有环 方法1 方法2 JAVA实现 问题扩展1 问题扩展2 判断链表是否有环 有一个单向链表,链表中有可能出现"环",就像下图这样.那么,如何用程序来 ...

  8. C程序:如何判断链表是否有环

    C程序:如何判断链表是否有环 这是个常见的面试题哦,总之我面试的时候遇到过, 当时没有答上来,回去后想出来下面的方法一,该法还有个附加优点,可以判断出链表在哪个地方形成环的(即如果想拆开这个环,从哪个 ...

  9. 数据结构-链表(判断链表是否有环)

    如何判断链表是否有环 方法1:采用快慢指针 /***************************** 函数名称:JudgmentLinkRing_1(PtrList list)* 功能描述:判断链 ...

最新文章

  1. 包括 一个 20像素的黑条条
  2. 在用户控件中用户登录后台脚本判断
  3. MyBatis 通用Mapper 入门教程
  4. Linux-手动释放linux内存cache
  5. eclipse中的maven build 、maven clean 、 maven install作用
  6. (五)操作系统安全概念和设计思想
  7. zabbix-server 的安装-centos7
  8. Win7下快速预览各种类型的文本文件
  9. 我女朋友让我删前任,我明明删了她还是要分手...
  10. 25 个精美的后台管理界面模板和布局
  11. 分享几个大数据相关岗位的职责和面试问题
  12. 使用小波变换进行灰度图像的融合
  13. mysql字符校对规则作用_(2)MySQL字符集及校对规则的理解
  14. QAM识别算法matlab,16qam调制识别matlab
  15. 博客9-12css2
  16. SSLOJ·马蹄印【DFS】
  17. 创建用户要给session权限,报错:user lacks CREATE SESSION privilege
  18. vue常用下载的依赖
  19. Excel操作报错 Application excelApp = new Application()异常
  20. python 惰性属性_python中惰性对象

热门文章

  1. 据说看完这21个故事的人,30岁前都成了亿万富翁。你是下一个吗?
  2. 广告条随滚动条的移动而移动
  3. 如何在DataGrid里面使用动态图形表示数字
  4. 在ASP.NET中跨页面实现多选
  5. bug诞生记——隐蔽的指针偏移计算导致的数据错乱
  6. tiny-cnn开源库的使用(MNIST)
  7. 【C++】C++11 STL算法(三):分隔操作(Partitioning operations)、排序操作(Sorting operations)
  8. linux 测试环境启用jar_Linux下用java -jar运行可执行jar包的方法教程
  9. c++ ofstream 文件不存在_使用C语言中的头文件有什么技巧和注意事项吗?为什么不直接包含C文件呢?...
  10. ios TableView编辑状态多选框的修改