91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java的單鏈表環操作有哪些

發布時間:2021-12-27 16:54:18 來源:億速云 閱讀:169 作者:iii 欄目:大數據

本篇內容介紹了“java單鏈表環的操作有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

判斷鏈表中是否有環

先來看一張圖:

java的單鏈表環操作有哪些  

我們能夠清楚的看到,在這個單鏈表中,是有環的。那么使用代碼,該如何判斷它是否有環呢?

先別著急看代碼,先和阿粉一起來分析一下,有了思路,代碼實現相對就比較容易。

判斷鏈表中是否有環,可以從頭結點開始,依次遍歷單鏈表中的每一個節點。每遍歷一個節點,就和前面的所有節點作比較,如果發現新節點和之前的某個節點相同,則說明此節點被遍歷過兩次,說明鏈表有環,反之就是沒有。

但是仔細看一下這種方法,你會發現這種方法很耗時耗力,因為每遍歷一個節點,都要把它和前面所有的節點都比較一遍。別著急,阿粉還有一個很巧妙的方法,就是使用兩個指針。這樣思路就可以這樣想:

使用兩個指針,一個快指針,一個慢指針。快指針每次走 2 步,慢指針每次走 1 步。如果鏈表中沒有環,則快指針會先指向 null 如果鏈表中有環,則快慢指針一定會相遇。

思路打通,咱們就可以使用代碼來進行實現了:

/**
* 判斷鏈表是否有環
*/
public class IsHasLoop {
   public static class Node{
       private int data;
       private Node next;
       public Node(int data,Node next){
           this.data=data;
           this.next=next;
       }
       public int getData(){
           return data;
       }
   }
   public static void main(String[] args){
       // 初始化單鏈表
       Node node5=new Node(5,null);
       Node node4=new Node(4,node5);
       Node node3=new Node(3,node4);
       Node node2=new Node(2,node3);
       Node node1=new Node(1,node2);
       // 讓 node5 的指針指向 node1 形成一個環
       node5.next=node1;

       boolean flag=isHasLoop(node1);
       System.out.println(flag);

   }
   public static boolean isHasLoop(Node list){
       if (list == null){
           return false;
       }

       Node slow=list;
       Node fast=list;

       while (fast.next != null && fast.next.next != null){
           // 慢指針走一步,快指針走兩步
           slow=slow.next;
           fast=fast.next.next;
           // 如果快慢指針相遇,則說明鏈表中有環
           if (slow==fast){
               return true;
           }
       }
// 反之鏈表中沒有環
       return false;
   }
}
   

求環長

現在判斷鏈表中是否有環這個問題已經解決了,阿粉覺得不能到此為止,思路就向外擴散了一下,既然有環了,如果想要求環長該怎么辦呢?

既然快慢指針相遇了,阿粉記錄下此時的位置,接下來再讓滿指針繼續向前走,每次走 1 步,這樣當慢指針再次走到相遇時的位置時,慢指針走過的長度不就是環長嘛

public static int getLength(Node list){
       // 定義環長初始值為 0
       int loopLength=0;
       Node slow=list;
       Node fast=list;

       while (fast != null && fast.next != null) {
           // 慢指針走一步,快指針走兩步
           slow=slow.next;
           fast=fast.next.next;

           // 第一次相遇時跳出循環
           if (slow == fast) break;
       }
       // 如果 fast next 指針首先指向 null 指針,說明該鏈表沒有環,則環長為 0
       if(fast.next == null || fast.next.next == null){
           return 0;
       }
       // 如果有環,使用臨時變量保存當前的鏈表
       Node temp = slow;
       // 讓慢指針一直走,直到走到原來位置
       do{
           slow = slow.next;
           loopLength++;
       } while(slow != temp);

       return loopLength;
}
   

求入環點

既然有環了,也求出了環長,那么入環點應該也知道了吧?阿粉對于求入環點這個問題有點兒懵,就畫了一張圖出來:

java的單鏈表環操作有哪些  

如上圖,我們假設:

入環點距離頭結點距離為 D 入環點與首次相遇點較短的距離為 S1 入環點與首次相遇點較長的距離為 S2 當兩個指針首次相遇時,慢指針一次只走 1 步,則它所走的距離為:D+S1 快指針每次走 2 步,多走了 n(n>=1) 圈,則它所走的距離為:D+S1+n(S1+S2) 快指針速度為慢指針的 2 倍,則:2(D+S1)=D+S1+n(S1+S2) 上面等式,整理可得:D=(n-1)(S1+S2)+S2

如果讓 (n-1)(S1+S2) 為 0 ,是不是 D 和 S2 就相等了?也就是說,當兩個指針第一次相遇時,只要把其中一個指針放回到頭結點位置,另外一個指針保持在首次相遇點,接下來兩個指針每次都向前走 1 步,接下來這兩個指針相遇時,就是要求的入環點。

有點兒像做數學題的感覺,還好阿粉的數學功底還是有那么一丟丟的。

基于上面的思路,代碼就很容易實現了:

public static Node entryNodeOfLoop(Node list){
       Node slow=list;
       Node fast=list;
       while(fast.next != null && fast.next.next != null){
           // 慢指針走一步,快指針走兩步
           slow=slow.next;
           fast=fast.next.next;

           // 第一次相遇時跳出循環
           if (slow == fast) break;
       }
       // 如果 fast next 指針首先指向 null 指針,說明該鏈表沒有環,則入環點為 null
       if (fast.next == null || fast.next.next == null){
           return  null;
       }
       // 第一次相遇之后,讓一個指針指向頭結點,另外一個指針在相遇位置
       // 兩個指針每次走 1 步,相遇為止,此時相遇節點即為入環點
       Node head=list; // 頭結點
       Node entryNode=slow;    // 相遇節點
       while (entryNode != head){
           entryNode=entryNode.next;
           head=head.next;
       }
       return entryNode;
}

“java單鏈表環的操作有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

盐源县| 徐州市| 武威市| 大余县| 英山县| 清流县| 策勒县| 英吉沙县| 丹巴县| 荣成市| 大余县| 辽源市| 崇信县| 清丰县| 西乌| 通辽市| 沁阳市| 苍溪县| 佳木斯市| 社旗县| 宁国市| 洞口县| 临邑县| 玉林市| 安丘市| 冕宁县| 内乡县| 南康市| 烟台市| 津南区| 桃园县| 贡觉县| 桦南县| 宁晋县| 广东省| 浏阳市| 温泉县| 来安县| 稻城县| 交口县| 宁德市|