判断一个单链表中是否有环

来源:互联网 发布:淘宝上传图片模糊 编辑:程序博客网 时间:2024/06/06 02:23

最近在学习数据结构中关于链表的部分,顺序表、单链表、循环链表、双向链表、静态链表和不带头结点的各种链表….
直到遇见了带环的单链表,我才发现这个世界没有最变态的东西,只有更变态的东西…..
话不多说,开始今天的主题吧!顾名思义,有环的单链表就是一个单链表中出现了一个环,但是这个环比较特殊,它的位置很有讲究。

我们知道,单链表的结构为:

这里写图片描述

而且在链表中,一个数据节点只能有一个前驱和一个后继,那么单链表要想成环,就不能像这样:

这里写图片描述

上面这种环,会把后面的数据结点搞丢,这样是万万不行的!

所以,正确的环应该出现在尾巴处,尾结点指向链中的某一数据节点。(指向头结点的话,就是循环链表)

这里写图片描述

既然知道了环的存在,那么如何判断一个单链表中出现了环呢?

我们假定有两个指针,一个叫快指针,一个叫慢指针,两个指针同时开始走,只要表中出现环,那么它们就会一直不停地走直到在环中相遇!
这就类似两个选手进行3600米的长跑竞赛,一个更强些,速度较另一个快,但是他在领先的同时,还是会和较慢的那位在赛道的某一点相遇。

这里写图片描述

以下就是具体的代码实现:

bool IsCircle(List plist){    Node *p = plist;//快指针    Node *q = plist;//慢指针    while(1)    {        p = p->next->next;        q = q->next;        if(p->next==NULL || p->next->next==NULL)//没成环,直接找到结尾        {            return false;        }        if(p->next == q->next)//找到环        {            return true;        }    }}

让我们再结合图,来分析一下具体的找环过程。

1.判断单链表是否有结尾
用慢指针p->next去寻结尾,因为快指针的步子太大了。
就用p->next->next==NULL去代替快指针的步长,因为如果用慢指针和快指针同时去判断的话,快指针可能很快就会越界、程序进而崩溃。

这里写图片描述

2.若快慢指针在某点相遇,则有环
这里写图片描述

他们一定会在这个环里的某点相遇,因为如果有环的话,就会一直在这里面循环运动了。

以上就是关于单链表中环的描述,如有问题,还请您不吝赐教!

原创粉丝点击