判断list是否存在环

本文介绍了一种通过快慢指针来检测单向链表中是否存在环的方法,并进一步提供了寻找环入口节点的算法实现。利用两个速度不同的指针,一个每次移动一步,另一个每次移动两步,如果存在环,二者必定会在环内相遇。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出如下结构:
struct node
{
struct *next;
};
typedef stuct node Node;
 
bool getCycle(){
Node* temp1 = head;//(假设head就是这个链表的头)
Node* temp2 = head;
while(head->next!=NULL)
{
temp1 = temp1->next;//步长为1
temp2 = temp2->next->next;//步长为2
if(temp1 == temp2)
return ture;
head=head->next;
}
return false;

}

写一段代码判断一个单向链表中是否有环。

原理:

设置两个指针,开始都指向链表头,然后其中一个指针每次向前走一步,另一个指针每次向前走两步,如果快的遇到NULL了,证明该链表中没有环,如果有环,快的指针每次都要比慢的多走一步,最终两个指针会相遇,(注意:这里快指针不会跳过慢指针而不相遇,因为它每次都只比慢指针多走一个单位)
bool judge(list *head){if(head == NULL){return false;//没有环}
list *pFast = head;
list *pSlow = head;
while(pFast-next != NULL && pFast-next-next != NULL){pFast = pFast-next-next;
pSlow = pSlow-next;


http://blog.youkuaiyun.com/guoyong10721073/article/details/8144401

多种思路:

http://blog.youkuaiyun.com/htyurencaotang/article/details/11481875

http://www.cnblogs.com/shuaiwhu/archive/2012/05/03/2480509.html

http://www.xuebuyuan.com/1570516.html

为啥步长是1?

http://blog.chinaunix.net/uid-21393885-id-88130.html

综合:http://blog.youkuaiyun.com/thefutureisour/article/details/8174313

http://www.cnblogs.com/zhyg6516/archive/2011/03/29/1998831.html


题目描述

一个链表中包含环,请找出该链表的环的入口结点。
//第一步,找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,
//p2每次走二步,直到p1==p2找到在环中的相汇点。
//第二步,找环的入口。接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,
//设环中有n个节点,p2比p1多走一圈有2x=n+x; n=x;可以看出p1实际走了一个环的步数,
//再让p2指向链表头部,p1位置不变,p1,p2每次走一步直到p1==p2; 此时p1指向环的入口。
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* pHead)
    {
   if(pHead == NULL || pHead->next == NULL)
            return NULL;
        ListNode* p1 = pHead;
        ListNode* p2 = pHead;
        while(p2 != NULL && p2->next != NULL ){
            p1 = p1->next;
            p2 = p2->next->next;
            if(p1 == p2){
                p2 = pHead;
                while(p1 != p2){
                    p1 = p1->next;
                    p2 = p2->next;
                }
                if(p1 == p2)
                    return p1;
            }
        }
        return NULL;
    }
};
















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值