zoukankan      html  css  js  c++  java
  • 判断链表是否有环,求环的入口以及环长

    1。判断链表是否带环 

    判断链表是否带环,我们可以采用在头结点设两个指针,一个叫fast,一个叫slow,fast一下走两步,而slow一下走一步。如果链表中存在环的话,那么fast和slow必定会在环中相遇。若链表中没有环的话,那么fast必定现于slow指针先到达链表的尾节点(->next = Null)。我们现在来思考一个问题,为什么链表中存在环,则slow和fast会在环中相遇?这个道理,我们可以联想我们跑步追赶的例子,跑道是前面一段直行路, 

    后面是一个圆圈,当跑步选手进入环形跑道之后就只能在环形跑道里面继续奔跑。有两名选手在起点同时出发,那么我们很容易明白跑得快的选手肯定会追赶上跑的慢的选手。哎,生活中都是学问啊,有木有??? 

    2. 求环的入口点 

    老实说,求环的入口点有点复杂。我也是在看了一些前辈们的文章才比较清楚到底是怎么一回事(http://www.cnblogs.com/youxin/p/3303172.html)。我们先看一幅图,这幅图也是我在程序中构造带环链表的原型。 

     
     



    如上图所示,12为带环链表的入口点,简单分析可知243是fast和slow的相遇点(鹊桥相会啊==!),a为环入口点到头结点的路程,x为相遇点到环入口点的路程。我们假设slow指针走过的路程为s,那么fast指针走过的路程则为2s,假设环长为c。且有 

    2s = s + nc 

    s = a + x 

    有上述式子,我们可以得到 

    a + x = nc 

    a = nc – x 

    a = (n – 1)c + c -x 

    式子化来化去,到这儿,我们是不是感觉有点不对经,好想如果在头结点位置和相遇点位置分别再派出两名跑步选手,并且他们都每次只跑一步,好像会在环的入口点相遇啊!!!恭喜你,答对啦!具体原因我们再分析分析最后一个式子就能明白了。啊。。。。求个环的入口点,我容易嘛我?? 

    3.求环长 

    求环长就比较容易啦,没用到什么数学知识,对于数学知识捉急的我真是终于松了一口气。就是再环的入口点设一指针和一计数器,让这一指针在环里面跑,计数器不断自增。当这一指针回到环的入口点的时候,环长就出来啦! 

    4.完整代码请见: 
    http://www.anycodex.com/blog/?p=97 

    5.测试平台www.anycodex.com 

    转!!http://www.douban.com/group/topic/49203127/?type=like

    http://www.cnblogs.com/youxin/p/3303172.html

  • 相关阅读:
    Virtuabox 虚拟机克隆方法
    CentOS 7 防火墙 出现Failed to start iptables.service: Unit iptables.service failed to load
    Linux系统下安装rz/sz命令及使用说明
    os、sys模块
    collections、random、hashlib、configparser、logging模块
    time、datatime模块
    正则表达式、re模块
    递归、二分查找法
    内置函数、匿名函数
    生成器进阶、生成器表达式
  • 原文地址:https://www.cnblogs.com/joyclub/p/4492481.html
Copyright © 2011-2022 走看看