参考:http://blog.csdn.net/wenqian1991/article/details/17452715

上面分析了 根据这张图

推倒出 数学公式。 刚接触 不能一下弄明白。下面结合上面文章的分析。仔细推倒一下 ,

一般设置 快指针 速度是 慢指针的2倍。及 快指针每次遍历两个指针, 慢指针每次遍历1个指针。

假设上图 快慢指针 在E点相遇,那 相遇点离循环节点D 之间距离是X.  头结点A 离循环节点D 距离为K.

那么在两指针相遇时,各自走过得距离(这里可以吧上图想成是 一个操场,起点不在操场内):

慢指针:

K + X + n*(X+Y) = m;//X+Y 绕环一圈的距离;n 慢指针 总共绕了几圈在环内.

快指针:

试想下 快指针是慢指针 速度的2倍,当它们相遇时 所用的时间是一样的。那么快指针 走过得距离是

2*m;

也等于

K+X +N*(X+Y) = 2*m;//N为快指针绕过得圈数

联立做差上面两公式。

(N-n)*(X+Y) = m; 及

(N-n)*(X+Y) = K+X+n*(X+Y);//这里X+Y 环长是个定值。 假设环长为M

有:(N-n)*M = K+X+n*M;

有:K+X = (N-2*n)*M ;

最终的推倒公式 出来啦。及头节点A 到 循环节点D 的距离  加上  相遇点E离循环节点D  是 环长的整数倍。

这个公式试用于 0 型循环链表  和 6型循环链表。

对于前者 起K 和 X 都为0;快慢指针起点都是循环节点(0型 任意一点都是循环节点)
那么有 (N-2*n)*M = 0;

及 N = 2*n;  相遇时 快慢指针所绕 环的圈数 前者是后者的2倍。 可以想象速度是2呗,所用时间相同。

这里跟环有多少节点没有关系。

上面只是找到了相遇节点。如何找到循环节点。对于6型循环链表。

还是上面推倒公式:

K+X = (N-2*n)*M;//假设N-2*n = Q; 单位为圈数。

有K+X=Q*M;   //再假设快慢指针能再循环节点相遇,那么X = 0;

K = Q*M; //Q 的值和K 成正比,这个公式成立条件是 快慢指针相遇 在环上的任意一个点,

假如是E点,结合公式  从E点转Q*M个节点 正好= K 。K的终点正好是循环节点D,及 如果快指针从起点A 走过K  和 慢节点 从E 走过M*Q 相遇节点正好是D循环节点,前提是快慢指针速度相同。

假设将快指针 从头节点开始。慢指针从上次快慢指针相遇点 开始。 两者已相同速度移动。

当快指针走的D 循环节点走过距离为K,慢指针 走到D 循环节点走过的距离为Q*M;

此时 二者相遇 节点就是循环节点。

分析下代码:

  1. Node* findBeginning(Node *pHead)
  2. {
  3. if (NULL == pHead)
  4. return NULL;
  5.  
  6. Node *fast = pHead;
  7. Node *slow = pHead;
  8.  
  9. /*判断是否存在环*/
  10. while (fast->pnext != NULL) //两种情况会跳出循环
  11. {
  12. fast = fast->pnext->pnext;
  13. slow = slow->pnext;
  14.  
  15. if (NULL == fast)
  16. return NULL;
  17. if (fast == slow)
  18. break;
  19. }
  20.  
  21. if (NULL == fast->pnext) //判断是哪种情况导致跳出循环
  22. return NULL;
  23.  
  24. /*查找环起点*/
  25. fast = pHead;
  26. while (fast != slow)
  27. {
  28. fast = fast->pnext;
  29. slow = slow->pnext;
  30. }
  31.  
  32. return fast;
  33. }

关于快慢指针算法:

不仅限于 循环链表问题。

比如查找一个  未知长度链表中中心节点

可以先遍历长度,在遍历到长度/2处返回节点。显然这样 算法不够优化,

使用快慢指针 遍历。快指针速度为 慢得 2倍。

快指针遍历完,返回的慢指针 正好是 长度/2 的节点。

c 链表之 快慢指针 查找循环节点的更多相关文章

  1. c 链表之 快慢指针 查找循环节点(转)

    上面分析了 根据这张图 推倒出 数学公式. 刚接触 不能一下弄明白.下面结合上面文章的分析.仔细推倒一下 , 一般设置 快指针 速度是 慢指针的2倍.及 快指针每次遍历两个指针, 慢指针每次遍历1个指 ...

  2. 复习下C 链表操作(双向循环链表,查找循环节点)

    双向循环链表  和 单向循环链表 查找循环节点 思路都是一样. 快慢指针查找法. 理论可参考 c 链表之 快慢指针 查找循环节点 typedef struct Student_Double { ]; ...

  3. sort-list——链表、快慢指针找中间、归并排序

    Sort a linked list in O(n log n) time using constant space complexity. 链表,快慢指针找中点,归并排序. 注意判断条件fast-& ...

  4. 复习下C 链表操作(单向循环链表、查找循环节点)

    循环链表 稍复杂点. 肯能会有0 或 6 字型的单向循环链表.  接下来创建 单向循环链表 并 查找单向循环链表中的循环节点. 这里已6字型单向循环链表为例. //创建 循环链表 Student * ...

  5. linked-list-cycle-ii——链表,找出开始循环节点

    Given a linked list, return the node where the cycle begins. If there is no cycle, returnnull. Follo ...

  6. reorder-list——链表、快慢指针、逆转链表、链表合并

    Given a singly linked list L: L0→L1→…→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do thi ...

  7. leetcode题目234.回文链表(快慢指针+辅助空间-简单)

    题目描述: 请判断一个链表是否为回文链表. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你能否用 O( ...

  8. [LeetCode题解]142. 环形链表 II | 快慢指针

    解题思路 本题是在141. 环形链表基础上的拓展,如果存在环,要找出环的入口. 如何判断是否存在环,我们知道通过快慢指针,如果相遇就表示有环.那么如何找到入口呢? 如下图所示的链表: 当 fast 与 ...

  9. 无表头单链表的总结----从a链表中删去与b链表中有相同ID的那些节点

    #include"head.h" struct Student* del_same_ID(struct Student*p1, struct Student*p2) { struc ...

随机推荐

  1. Python debug 调试;

    F9:执行跳到下一个断点 F8:执行下一步 F7:进入函数

  2. 关于MIS 系统所需技术和含义

    操作系统的作用在于 1资源管理 2人机交互.它提供各个应用软件的运行平台,也为用户提供交互界面.所需技术:一.b/s架构B/S结构即浏览器和服务器结构,在这种结构下,用户工作界面是通过WWW浏览器来实 ...

  3. 内置函数 filter zip map

    1. 基本内置函数: 2. enumerate :  枚举 把列表转化为有索引的字典: 3. eval 和 exec 4. 过滤函数  filter 5. map 函数批量修改: 6. 配对函数 zi ...

  4. NumPy学习(索引和切片,合并,分割,copy与deep copy)

    NumPy学习(索引和切片,合并,分割,copy与deep copy) 目录 索引和切片 合并 分割 copy与deep copy 索引和切片 通过索引和切片可以访问以及修改数组元素的值 一维数组 程 ...

  5. 004.Docker镜像管理

    一 镜像基本操作 镜像是一个包含程序运行必要依赖环境和代码的只读文件,其本质是磁盘上一系列文件的集合.它采用分层的文件系统,将每一次改变以读写层的形式增加到原来的只读文件上.镜像是容器运行的基石. 1 ...

  6. LeetCode刷题笔记--Python--28. 实现strStr()

    class Solution: def strStr(self, haystack, needle): """ :type haystack: str :type nee ...

  7. js算法初窥03(搜索及去重算法)

    前面我们了解了一些常用的排序算法,那么这篇文章我们来看看搜索算法的一些简单实现,我们先来介绍一个我们在实际工作中一定用到过的搜索算法——顺序搜索. 1.顺序搜索 其实顺序搜索十分简单,我们还是以第一篇 ...

  8. 程序猿(媛)的葵花宝典-- 必备idea 插件plugins 提高编码效率

    最近发现了几个非常好用   提高编码效率 的idea 插件 跟大家分享一下,,,不用谢我!!!!!!!!!!!!! 因为idea自带的插件下载可能连接不上服务器而导致插件下载失败,所以这里推荐使用引入 ...

  9. 洛谷 P1114 “非常男女”计划

    To 洛谷.1114 “非常男女”计划 题目描述 近来,初一年的XXX小朋友致力于研究班上同学的配对问题(别想太多,仅是舞伴),通过各种推理和实验,他掌握了大量的实战经验.例如,据他观察,身高相近的人 ...

  10. 用单片机控制LED灯(项目)

    #include <reg52.h> #define uchar unsigned char sbit LED_RED = P2^; sbit LED_GREEN = P2^; sbit ...