zoukankan      html  css  js  c++  java
  • 检测链表是否存在环的算法证明

    今天看到c专家编程的最后,有一处关于检测链表是否存在环的算法介绍,这个问题和算法之前在很多地方有看见,大致是有三个问题:1.给你一个单向链表判断是否有环;2.求出环的长度;3.给出环的开始节点。算法是这样:让两个指针指向表头,一个每次移动一步,叫做慢指针,一个每次移动两步,叫做快指针,一直循环移动,如果最后两者都碰到NULL指针则表示没有环,如果最后两者指向同一个节点表示有环。至于问题2,3则是可以扩展得到,从快慢指针相遇的那个节点开始,令一个新的指针开始遍历,他从起点回到起点所经历过的步数就是所求长度length,而环的开始节点可以这样求,让一个指针p1指向链表头,另一个p2指向离他length步的节点,p1,p2同时往前步步移动,他们相遇的节点既是环的起点。

    问题2,3依赖问题1,且显而易见,但是问题1的解法怎么用准确的数学方法来证明,在存在环的情况下快指针一定会和慢指针相遇吗?这里有一个比较好的证明:http://stackoverflow.com/questions/3952805/proof-of-detecting-the-start-of-cycle-in-linked-list

    证明过程大致如下:

    enter image description here

    链表如上图所述,pSlow,pFast分别对应快慢指针,在指针在链表上移动的时候有

    pSlow = x

    pFast = 2(x+1)

    当pSlow到达m时pFast = 2(m+2), 这时候pSlow与pFast都在环上移动,当pSlow移动了t步后

    pSlow = m + t  ==>  m + t %n

    pFast  = 2*(m + t )  ==> m + (m + 2t)%n

    现在,当且仅当m +t%n = m +(m+2t)%n 时 pSlow = pFast,快慢指针相遇,解这个等式:

    m +t%n = m +(m+2t)%n  ==>  t%n = (m+2t)%n ==> (m+t)%n = 0

    m是非负整数,n是正整数,t是正整数,显然对于任意的m,n必然存在一个t使得等式成立。

  • 相关阅读:
    C++多态性的总结
    php 基于curl 实现,模拟多线程任务
    php 解决跨域问题
    vue-cli 使用步骤
    php 图片转成base64 前后台示例
    jq 实现选项卡效果
    javascript仿es6的map类
    PHP生成word并可下载
    vue 实现的树形菜单
    vue之路由的基本用法
  • 原文地址:https://www.cnblogs.com/persistentsnail/p/3294917.html
Copyright © 2011-2022 走看看