链表 判断是否有环

1、判断链表是否有环,一般采用两个指针,一个快指针,一个慢指针,假如两个指针能够相遇说明有环

2、找到环的起点,这里有一定理,按照顺序迭代,从   链表头到连接点的距离=相遇点到连接点的距离

证明如下

假设整个链表长L=a+b,a为链头到连接点的距离,b为环长度,Q为相遇点,k是连接点到Q的距离,证明:a=b-k;

慢指针走的距离是s1=a+k,则快指针走的距离是s2=a+k+b,同时快指针速度又是慢指针的2倍,则S2=a+k+b=2(a+k);

b=a+k;a=b-k,得证。

代码如下:

    public class ListNode
    {
        int val;
        ListNode next;
        public ListNode(int x) {
            // TODO Auto-generated constructor stub
            val=x;
        }
    }

    public boolean hascircle(ListNode l)
    {
        if(l==null || l.next==null)
            return false;
        ListNode slow=l;
        ListNode fast=l;
        while(fast!=null && fast.next!=null)
        {
            slow=slow.next;
            fast=fast.next.next;
            if(fast==slow)
                return true;
        }
        return false;
    }

    public ListNode findConnection(ListNode head)
    {
        ListNode slow=head,fast=head;
        while(fast!=null && fast.next!=null)
        {
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast)
                break;
        }//找到出口或者找到碰撞点
        if(fast!=null && fast.next!=null)//如果是出口,直接输出null
            return null;
        slow=head;
        if(slow!=fast)
        {
            slow=slow.next;
            fast=fast.next;
        }
        return slow;
    }

 

posted @ 2015-07-10 18:31  Maydow  阅读(127)  评论(0编辑  收藏  举报