判断链表是否有环,求环的入口以及环长

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

原文地址:https://www.cnblogs.com/joyclub/p/4492481.html