連結串列檢測環演算法,找到環中的出口節點
- 如何判斷一個連結串列有環
方法是使用快慢指標,通過一個slow指標(每次都指向下一個),一個quick指標(每次都指向下面兩個)
因為假設有環的話,quick會追上slow指標
找到環出口就是通過slow指標指向頭節點,quick指標指向之前環的交叉點,然後一直以不同速度遍歷直到相遇
這樣找到的就是出口節點
java實現方法如下
1 package 測評; 2 3 import org.junit.Test; 4 5 public class Main5 { 6// node 7private static class node { 8int val; 9node next = null; 10 11public node(int a) { 12this.val = a; 13} 14} 15 16// 17public static node create() { 18// 建立 19node first = new node(0); 20node node = first; 21int i = 1; 22while (i < 10) { 23node.next = new node(i); 24node = node.next; 25i++; 26} 27i = 0; 28node node2 = first; 29while (i < 6) { 30if (i == 5) { 31node.next = node2; 32} else { 33node2 = node2.next; 34} 35i++; 36} 37 38return first; 39} 40// 41@Test 42public void test_circle() { 43node first = create(); 44// 快慢指標方法判斷是否為環 45node quick = first; 46node slow = first; 47int i = 0; 48while (i < 1000) { 49quick = quick.next.next; 50slow = slow.next; 51if (quick == slow) { 52System.out.println("這個是一個環"); 53break; 54} 55i++; 56} 57} 58// 59//主要是通過快慢指標來判斷,慢指標從first節點觸發,快指標從交叉點出發,最後的交點就是出口節點 60@Test 61public void test_getNode() { 62node first = create(); 63 64// 快慢指標方法判斷是否為環 65node jiaodian = null; 66node quick = first; 67node slow = first; 68int i = 0; 69while (i < 1000) { 70quick = quick.next.next; 71slow = slow.next; 72if (quick == slow) { 73break; 74} 75i++; 76} 77// 78slow = first; 79while(i<1000) { 80slow = slow.next; 81quick = quick.next.next; 82if(slow == quick) { 83System.out.println("出口節點"+slow.val); 84break; 85} 86} 87} 88 }
- 第二個問題就是判斷兩個連結串列是否有交點
判斷還是很簡單的,只要將兩個連結串列遍歷到尾節點,如果尾節點相同,這樣就證明這兩個連結串列是有交點的
如何找到兩個連結串列相交的節點?
方法:遍歷兩個連結串列的長度,然後長連結串列長度減去短連結串列長度為K,讓長連結串列減去K,然後兩個連結串列逐個對比
Java程式碼
1 @Test 2public void test() { 3//建立兩個連結串列 4node first1 = new node(0); 5node node1 = first1; 6node first2 = new node(0); 7node node2 = first2; 8int i=0; 9while(i<5) { 10node1.next = new node(i); 11i++; 12} 13i=0; 14while(i<5) { 15node2.next = new node(i); 16i++; 17} 18node ban = new node(6); 19node node3 = ban; 20i=0; 21while(i<5) { 22node3 = new node(i+5); 23i++; 24} 25node1.next = ban; 26node2.next = ban; 27// 28//這裡是判斷 29int length_1 = 0; 30int length_2 = 0; 31node1 = first1; 32node2 = first2; 33while(node1 != null) { 34length_1++; 35node1 = node1.next; 36} 37while(node2 != null) { 38length_2++; 39node2 = node2.next; 40} 41 42int k = 0; 43if(length_1>=length_2) { 44k = length_1-length_2; 45int j = 0; 46while(j<k) { 47first1 = first1.next; 48j++; 49} 50}else { 51k = length_2 - length_1; 52int j = 0; 53while(j<k) { 54first2 = first2.next; 55j++; 56} 57} 58while(true) { 59if(first1 == first2) { 60System.out.println("共同節點"+first1.val); 61break; 62} 63first1 = first1.next; 64first2 = first2.next; 65} 66}