发现链表的中间节点/翻转链表/ 是否有环,环大小,环入口

这里输入代码
/**
     * 快速发现一个链表的中间节点
     * 使用两个指针 1:一次走两步。2:一次走一步, 当一个指针走完,第二个指针则为中间节点
     * [@return](https://my.oschina.net/u/556800)
     */

    public  static Node findMid( Node node){
        if(node==null) { return null;}
        if(node.next==null){return  node;}
        Node n1 = node;
        Node n2=node;
        while (n2.next!=null && n2.next.next!=null){

            n2 = n2.next.next;
            n1 = n1.next;
        }
        return n1;
    }
 /**
     * 翻转一个链表
     * [@return](https://my.oschina.net/u/556800)
     */
    public static  Node revise(Node node){
        if(node == null ) { return null;}
        if(node.next == null){ return node;};
        Node n1 = node;
        Node n2 = n1.next;
        n1.next = null;
        Node n3=n2;
        while (n3 !=null){
            n3=n2.next;
            n2.next = n1;
            n1= n2;
            if(n3!=null) {
                n2 = n3;
            }
        }
        return n2;
    }
 /**
     * 判断一个链表是否有环,环大小,环入口
     * @param node
     */
    public static  void ishuan(Node node){

        if(node ==null || node.next==null || node.next.next==null ){

            throw  new RuntimeException("Node Error");
        }
        Node show= node;
        Node fast= node;
        boolean hasHuan=false;
        while (fast!=null){
            show=show.next;
            if(fast.next==null){
                break;
            }
            fast = fast.next.next;
            if(show!=null && fast!=null && show.equals(fast)){
                System.out.println("有环");
                hasHuan=true;
                break;
            }
        }
        if(hasHuan == false) {   System.out.println("无环"); return;}

        /**
         * 环大小。 快指针继续走一圈,再次和慢指针 则为环的大小
         */
        int i=0;
        while (true){
            i++;
            fast = fast.next;
            if(fast.equals(show)){break;}
        }

        System.out.println("环大小为:"+i);

        /**
         * 表头到环入口长度为 X;相遇慢指针走的路为:s,则快指针走的路是 2s;环入口到相遇点的距离是y
         * 环的大小是r,相遇 快指针已经走了圈数是 n,则:
         * (1)  2s = s+nr   ->>   s=nr
         * (2)  s = x+y     ->>   nr=x+y ->>  y = nr-x;
         则快指针由表头开始走。每次一步一位。到达环点的距离则为 x。 慢指针由当前位置走,每次走一步。则 当 快指针移动到环入口时候
         的距离X,  根据  y = nr-x;  推算出,此刻慢指针也位于环点的入口
         */

        fast=node;

        while (true){
            if(fast.equals(show)){

                System.out.println("环点为:"+fast.v);
                break;
            }
            fast= fast.next;
            show=show.next;
        }


    }

猜你喜欢

转载自my.oschina.net/u/1388024/blog/1785069