上面分析了 根据这张图

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

一般设置 快指针 速度是 慢指针的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 的节点。

转自:http://www.cnblogs.com/tangbinblog/p/4125842.html

转载于:https://www.cnblogs.com/zl1991/p/6958202.html

c 链表之 快慢指针 查找循环节点(转)相关推荐

  1. 快慢指针寻找循环节点

    循环链表找循环开始的节点: //设置快慢指针 快指针一次走两个 慢指针一次走一个 第一次相遇后将快指针重新放到头部 //快指针一次走一个 慢指针一次走一个 第二次相遇的位置就是环开始的位置 题目 14 ...

  2. 试编写一个将双向循环链表逆置的算法_图解:链表的快慢指针,解决 80% 的链表面试题!...

    一.前言 链表是基本的数据结构之一,它与数组不同,数组在内存中存储,需要一块连续的内容空间来存储,对内存的要求比较高.例如我们需要 100MB 大小的数组,内存中就必须有一段连续的 100MB 的内存 ...

  3. 数据结构链表之单链表的快慢指针——3

    单链表之快慢指针 单链表的快慢指针简介 快慢指针指链表中定义两个指针,两个指针的移动速度一快一慢,一般快指针移动步长为慢指针的两倍 快慢指针适合解决的几个典型问题 中间值问题 单向链表是否有环问题 有 ...

  4. 环形链表的快慢指针相遇问题证明

    环形链表的快慢指针相遇问题证明 证明1:慢指针一定在环形链表一圈内遇上 首先假设慢指针的每次只走1步,快指针每次走2步,当慢指针走了k次后,慢指针共走了k步,而快指针走了2k步. 假如说,快指针和慢指 ...

  5. 链表中快慢指针的应用

    目录 一.链表的中间结点 二.回文链表 三.链表中倒数第K个结点 四.删除链表的倒数第n个结点 五.环形链表 六.环形链表Ⅱ 一.链表的中间结点 给定一个头结点为 head 的非空单链表,返回链表的中 ...

  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 th ...

  7. 程序员面试金典 - 面试题 02.06. 回文链表(快慢指针+链表反转)

    1. 题目 编写一个函数,检查输入的链表是否是回文的. 示例 1: 输入: 1->2 输出: false 示例 2: 输入: 1->2->2->1 输出: true 进阶: 你 ...

  8. LeetCode 143. 重排链表(链表反转+快慢指针)

    1. 题目 给定一个单链表 L:L0→L1→-→Ln-1→Ln , 将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→- 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换. ...

  9. LeetCode 234. 回文链表(快慢指针+链表反转)

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

最新文章

  1. DIV CSS left right top bottom定位
  2. Frighting的日常:第7天
  3. MySQL in语句内参数个数限制
  4. 我对NHibernate的感受(3):有些尴尬的集合支持
  5. DDos防御工具DDoS-Defender-v2.1.0
  6. 将Excel的数据导入DataGridView中[原创]
  7. 软件产品测试报告模板
  8. pdfminer识别pdf无法识别问题
  9. TCPIP网络编程项目式教程(微课版)
  10. 项目配置管理CM(Configuration Management)
  11. 01 复杂度分析(上):时间、空间复杂度讲解
  12. 【svn】svn的Replacing来历及解决办法
  13. 人民币金额由阿拉伯数值转换成汉字大写数值的函数
  14. Three.js 学习历程与总结
  15. 【Windows内核编程】Win10/Win11通过PspCidTable取得EProcess
  16. “京东区块链技术白皮书”解密互联网应用(附下载链接)
  17. 【video frame interpolation系列1】背景知识: forward and backward image warping (图像扭曲/变换)
  18. 安全研究 # 课题:二进制成分分析(Binary SCA)
  19. Android 12.0 第三方app安装完成后默认授予运行时权限
  20. IIC读取AS5600磁编码器并计算相对角度与圈数代码移植

热门文章

  1. hp 服务器系统无法启动不了怎么办,HP Elite X2 1011 G1 笔记本电脑 - 电脑无法启动至预启动执行环境...
  2. MySQL 数据库常用命令小结
  3. Visual Studio原生开发的20条调试技巧(下)
  4. ViewPage+Fragment的使用例子
  5. android oom 全解析
  6. C语言中不安全的函数
  7. MySQl笔记8:把good表中商品名为‘诺基亚xxxx‘的商品,改为‘HTCxxxx‘
  8. Windows中SQLite的编译及编程
  9. 汇编: 使用ds data
  10. python三十一:random模块