發現鏈表的中間節點/翻轉鏈表/ 是否有環,環大小,環入口

這裏輸入代碼
/**
     * 快速發現一個鏈表的中間節點
     * 使用兩個指針 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;
        }


    }
相關文章
相關標籤/搜索