单链表中是否有环的问题

   这篇是写单链表中是否有环的判断,环的长度,以及环的起始节点问题的思路以及实现。
   第一个问题就是判断是否有环:
   使用2个引用和一个循环可以解决这个问题,一个引用一次向后走2个节点,称为fast,一个引用一次向后走一个节点,称为slow,当fast与slow相遇时证明这个单链表有环,代码如下:
    public boolean haveCircle(){
        Node fast = this.head;
        Node slow = this.head;
        while(fast != null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }

        }
        return false;
    }
    第二个问题,环的长度,只需要记录下碰撞点的地址,从碰撞点的下一个节点遍历,再次回到这个点走过的节点数就是长度,代码如下:
public int getCircleNodeNum(){
        if(this.haveCircle() == false){
            return 0;
        }
        else{
            Node fast = this.head;
            Node slow = this.head;
            Node p = null;
            int count = 0;
            while(fast != null){
                fast = fast.next.next;
                slow = slow.next;
                if(fast == slow){
                    p = fast;
                    slow = slow.next;
                    count+=1;
                    break;
                }
            }
            while(slow != p){
                slow = slow.next;
                count++;
            }
            return count;

        }

    }
    最后一个问题,寻找循环的头,也就是这个环的连接点,遇到用到这个东西:

    **碰撞点到连接点的距离 = 头指针到连接点的距离**

    有了这个,一个引用从头开始走,另一个从碰撞点走,2个相遇时的那个节点就是这个环的连接点,代码如下:
public Node firstCircleNode(){
        //碰撞点到连接点的距离 = 头指针到连接点的距离
        if(this.haveCircle() == false){
            return null;
        }
        else{
            Node fast = this.head;
            Node slow = this.head;
            while(fast != null){
                fast = fast.next.next;
                slow = slow.next;
                if(fast == slow){
                    break;
                }
            }
            slow = head;
            while(slow != fast){
                slow = slow.next;
                fast = fast.next;
            }
            return slow;

        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值