判断链表是否有环 环距 入环点

package shujujiegou.Node;

public class Node {

private Node next;
private int data;

public Node(int data) {
    this.data = data;
}

public static void main(String[] args) {
    Node node1=new Node(1);
    Node node2=new Node(19);
    Node node3=new Node(4);
    Node node4=new Node(2);
    Node node5=new Node(10);

    node1.next=node2;
    node2.next=node3;
    node3.next=node4;
    node4.next=node5;
    node5.next=node1;

    System.out.println(isCycle(node1));


    findNode(node1);
}



/**
 * 判断是否有环  和 环距
 * @param head 链表头结点
 * @return
 */
private static boolean isCycle(Node head) {
    //指针1 移动一位
    Node p1=head;
    //指针2  移动两位
    Node p2=head;

    int n=0;

    while (p2!=null  && p2.next!=null){
        p1=p1.next;
        p2=p2.next.next;
        //指针重合 说明有环
        if (p1 == p2){
            //再走一次 再次重合为长度
            while (p2!=null  && p2.next!=null){
                p1=p1.next;
                p2=p2.next.next;
                n++;
                //指针重合 说明有环
                if (p1 == p2){
                    System.out.println(n+"环距");
                    return true;
                }
            }
            return false;
        }
    }
    return false;
}
/*
    寻找入环点
 */
private static boolean findNode(Node head) {
    //指针1 移动一位
    Node p1=head;
    //指针2  移动两位
    Node p2=head;

    int n=0;

    while (p2!=null  && p2.next!=null){
        p1=p1.next;
        p2=p2.next.next;
        //指针重合 说明有环
        if (p1 == p2){
            //p2为相遇点  p1指向头结点
            p1=head;
            while (p2!=null && p2.next !=null){
                //p1, p2各进一步
                p1=p1.next;
                p2=p2.next;

                //相遇点即为入环点
                if (p1==p2){
                    System.out.println(p1.data+"为入环点");
                    return true;
                }
            }
        }
    }
    return false;
}

}

在这里插入图片描述
在这里插入图片描述

	  /**
     * 求环索引
     * @param head
     * @return
     */
    public  static Node detectCycle(Node head) {
        Node left=head;
        Node right=head;

        while(right!=null && right.next!=null)
        {
            left=left.next;
            right=right.next.next;

            if(left==right){

                Node pre=head;
                while( right !=null && right.next !=null){
                    if(right == pre){
                        return pre;
                    }
                    right=right.next;
                    pre=pre.next;

                }

            }
        }
        return null;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值