zoukankan      html  css  js  c++  java
  • 如何判断单链表是否存在环

    原文:http://blog.csdn.net/liuxialong/article/details/6555850

    如何判断单链表是否存在环

    给定一个单链表,只给出头指针h:

    1、如何判断是否存在环?

    2、如何知道环的长度?

    3、如何找出环的连接点在哪里?

    4、带环链表的长度是多少?

    解法:

    1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。

    2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰撞所走过的操作数就是环的长度s。

    3、问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。

    该定理的证明可参考:http://fayaa.com/tiku/view/7/

    4、问题3中已经求出连接点距离头指针的长度,加上问题2中求出的环的长度,二者之和就是带环单链表的长度

    判断是否存在环的程序:

    [cpp] view plaincopy
     
    1. bool IsExitsLoop(slist *head)  
    2. {  
    3.     slist *slow = head, *fast = head;  
    4.   
    5.     while ( fast && fast->next )   
    6.     {  
    7.         slow = slow->next;  
    8.         fast = fast->next->next;  
    9.         if ( slow == fast ) break;  
    10.     }  
    11.   
    12.     return !(fast == NULL || fast->next == NULL);  
    13. }  

    寻找环连接点(入口点)的程序:

    [cpp] view plaincopy
     
    1. slist* FindLoopPort(slist *head)  
    2. {  
    3.     slist *slow = head, *fast = head;  
    4.   
    5.     while ( fast && fast->next )   
    6.     {  
    7.         slow = slow->next;  
    8.         fast = fast->next->next;  
    9.         if ( slow == fast ) break;  
    10.     }  
    11.   
    12.     if (fast == NULL || fast->next == NULL)  
    13.         return NULL;  
    14.   
    15.     slow = head;  
    16.     while (slow != fast)  
    17.     {  
    18.          slow = slow->next;  
    19.          fast = fast->next;  
    20.     }  
    21.   
    22.     return slow;  
    23. }  
  • 相关阅读:
    Linux下的目录结构
    VM
    代码命名规范
    java环境及配置
    Code::Blocks 使用Cygwin编译加调试
    vscode使用体会
    openwrt编译笔记
    ubuntu20 使用root登录
    程序员如何更好的表达自己的想法- Graphviz:关系图脚本绘制工具-转
    编译codelite心得
  • 原文地址:https://www.cnblogs.com/zhizhan/p/4570328.html
Copyright © 2011-2022 走看看