链表中的环

、什么是环:

        环:是链表里面出现指向自己或者指向这个结点前面的元素,从而使链表形成一个闭环的状态。

2、如何判断链表是否含有环

   方法1(最优解):快慢指针

      思路:设置两个指针p、q,开始都在头结点,但是p走一步,q走两步。这样子,如果是没有环的链表,p,q是不可能相遇的

但是如果链表里面含有环,则他们一定会相遇 

代码实现

3、求环的入口
        有了上面的知识,现在我们可以考虑一个新的问题,将环的入口求出来如上图,环的入口为3,那么我们怎么通过代码求出来呢?

        思路:同样,我们需要判断该链表是否为带环链表,使用快慢指针的方法。当两个指针相遇,即证明有环,此时:将p返回头节点,q留在相遇的结点,p,q再分别一步一步的进行遍历,当p,q再次相遇,则该节点必定为环的入口。

代码实现


struct ListNode* EntryNodeOfLoop(struct ListNode* pHead ) 
{
    struct ListNode*p = pHead;
    struct ListNode*q = pHead;
    if(pHead == NULL)
    {
        return NULL;
    }
    while(p != NULL&&p->next!=NULL)
    {
        p = p->next->next;
        q = q->next;
        if(q == p)//有环
        {
            p = pHead;
            while(q != p )//以相遇为条件进行循环遍历
            {
                p = p->next;
                q = q->next;
            }
            return p;
        }
    }
    return NULL;
}

也有一种取巧的方法

利用了C新建地址的特性
C malloc 的地址总是大于所有已有的地址
所以假如下一个地址小于上一个,
那必是之前经过的节点。

struct ListNode *detectCycle(struct ListNode *head) {

    for(;head;head=head->next)

        if ((head->next)<=head) return head->next;

    return NULL;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值