【Java数据结构】判断单链表是否有环,并且找出环的入口

一:判断是否有环
       思路:使用快慢引用法解决 是否有环
                        假设链表是一个有环链表,且由f指向c构成环。那么  使用两个指针   A 和 B,让两指针同时向后遍历  而且B的遍历速度是A的两倍,呢么如果是有环的话,B终究会追上A。因此我们可以 以AB是否相遇作为判断是否有环的必要条件。

下面是图例:

 

 

 

 

 

最终BA在e相遇,于是可以得出   此链表有环。

代码:


public Entry<E> isLoop(){
        Entry<E> fast = first , slow = first;//定义两个指针,分别是快和慢
        //遍历一遍链表,如果最后是null的话就代表没有环
        while (fast != null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
            //如果俩相遇了,代表有环
            if (fast == slow){
                return fast;
            }
        }
        return null;
    }

二:求出成环的位置
思路:s=vt(路程=速度*时间)用方程思想列等式解
            因为路程知道,速度知道(二倍关系),时间也知道(相等),所以可以列等式求关系。再用代码体现出关系,就可以解决这道题了。

           如图:假设链表是Link   fast是快的那个指针,Slow是慢的呢个指针,蓝色是fast走过的路程,绿色是slow走过的路程

                K是环的入口,P是快慢指针相遇的地方

                 a,b,c 分别代表三段长度。

 

所以图就可以变成:

 

然后,让指针从   相遇点p   和起始点  同时遍历,这样由于   c = a  所以p和first在k相遇,而k就是入口点。   

 


public Entry<E> getIntersectEntry(){
        Entry<E> meet = isLoop();
        if(meet == null){
            return null;
        }
        Entry<E> p = meet;
        Entry<E> q = first;
        while (p!=q){
            p = p.next;
            q = q.next;
        }
        return p;
    }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值