如何用JAVA程式來查詢連結列表是否包含迴圈
查詢連結串列是否包含迴圈的演算法
迭代連結串列時使用快速和慢速兩個指標。快速指標在每次迭代中移動兩個節點,而慢速指標移動到一個節點。如果連結串列包含迴圈或迴圈,那麼在迭代過程中,快指標和慢指標都會在某個點上相遇。如果它們不相交,並且快速或慢速將指向空,那麼連結串列就不是迴圈的,它不包含任何迴圈。這是精確的演算法
1)使用快速和慢速兩個指標
2)每次迭代快速移動兩個節點,慢速移動一個節點
3)如果快速和慢速相遇,則連結串列包含迴圈
4)如果fast指向空或fast.next指向空,則連結串列不是迴圈的。
下一部分包含Java程式來檢查連結串列是否包含迴圈,這是上述演算法的精確實現。該演算法也被稱為Floyd的迴圈查詢演算法,通常被稱為Tortoise and Hare演算法,用於查詢連結串列中的迴圈。
Java程式檢查連結串列是否為迴圈
這個Java程式使用LinkedList(不Java.UTI.LIKEDLIST)和連結串列的前一個節點類,修改了新增ToStTrn()方法和AppEntoTead()方法。另外,連結串列的iscyclic()方法用於實現邏輯,以確定連結串列是否包含迴圈。隨後is cyclic()如果連結串列是迴圈的,則返回true,否則返回false。
<font><i>/* * Java class to represent linked list data structure. */</i></font><font> <b>public</b> <b>class</b> LinkedList { <b>private</b> Node head; <b>public</b> LinkedList() { <b>this</b>.head = <b>new</b> Node(</font><font>"head"</font><font>); } <b>public</b> Node head() { <b>return</b> head;} <b>public</b> <b>void</b> appendIntoTail(Node node) { Node current = head; </font><font><i>//find last element of LinkedList i.e. tail</i></font><font> <b>while</b>(current.next() != <b>null</b>){ current = current.next(); } </font><font><i>//appending new node to tail in LinkedList</i></font><font> current.setNext(node); } </font><font><i>/* * If singly LinkedList contains Cycle then following would be true * 1) slow and fast will point to same node i.e. they meet * On the other hand if fast will point to null or next node of * fast will point to null then LinkedList does not contains cycle. */</i></font><font> <b>public</b> <b>boolean</b> isCyclic(){ Node fast = head; Node slow = head; <b>while</b>(fast!= <b>null</b> && fast.next != <b>null</b>){ fast = fast.next.next; slow = slow.next; </font><font><i>//if fast and slow pointers are meeting then LinkedList is cyclic</i></font><font> <b>if</b>(fast == slow ){ <b>return</b> <b>true</b>; } } <b>return</b> false; } @Override <b>public</b> String toString(){ StringBuilder sb = <b>new</b> StringBuilder(); Node current = head.next(); <b>while</b>(current != <b>null</b>){ sb.append(current).append(</font><font>"-->"</font><font>); current = current.next(); } sb.delete(sb.length() - 3, sb.length()); </font><font><i>// to remove --> from last node</i></font><font> <b>return</b> sb.toString(); } <b>public</b> <b>static</b> <b>class</b> Node { <b>private</b> Node next; <b>private</b> String data; <b>public</b> Node(String data) { <b>this</b>.data = data; } <b>public</b> String data() { <b>return</b> data; } <b>public</b> <b>void</b> setData(String data) { <b>this</b>.data = data;} <b>public</b> Node next() { <b>return</b> next; } <b>public</b> <b>void</b> setNext(Node next) { <b>this</b>.next = next; } @Override <b>public</b> String toString() { <b>return</b> <b>this</b>.data; } } } </font>
測試迴圈的連結串列
在本節中,我們將使用帶有兩個連結串列的Java main方法測試,一個包含迴圈而另一個不迴圈。 您甚至可以為isCyclic()方法編寫JUnit測試用例,以測試不同位置的迴圈的不同連結串列。 這是連結串列不包含任何迴圈的第一個測試。
<font><i>/** * * Java program to find if LinkedList contains loop or cycle or not. * This example uses two pointer approach to detect cycle in linked list. * Fast pointer moves two node at a time while slow pointer moves one node. * If linked list contains any cycle or loop then both pointer will meet some time. * * @author Javin Paul */</i></font><font> <b>public</b> <b>class</b> LinkedListTest { <b>public</b> <b>static</b> <b>void</b> main(String args[]) { </font><font><i>//creating LinkedList with 5 elements including head</i></font><font> LinkedList linkedList = <b>new</b> LinkedList(); linkedList.appendIntoTail(<b>new</b> LinkedList.Node(</font><font>"101"</font><font>)); linkedList.appendIntoTail(<b>new</b> LinkedList.Node(</font><font>"201"</font><font>)); linkedList.appendIntoTail(<b>new</b> LinkedList.Node(</font><font>"301"</font><font>)); linkedList.appendIntoTail(<b>new</b> LinkedList.Node(</font><font>"401"</font><font>)); System.out.println(</font><font>"Linked List : "</font><font> + linkedList); <b>if</b>(linkedList.isCyclic()){ System.out.println(</font><font>"Linked List is cyclic as it contains cycles or loop"</font><font>); }<b>else</b>{ System.out.println(</font><font>"LinkedList is not cyclic, no loop or cycle found"</font><font>); } } } Output: Linked List : 101-->201-->301-->401 LinkedList is not cyclic, no loop or cycle found </font>
現在讓我們改變連結串列,使其包含迴圈
<font><i>//creating LinkedList with 5 elements including head</i></font><font> LinkedList linkedList = <b>new</b> LinkedList(); linkedList.appendIntoTail(<b>new</b> LinkedList.Node(</font><font>"101"</font><font>)); LinkedList.Node cycle = <b>new</b> LinkedList.Node(</font><font>"201"</font><font>); linkedList.appendIntoTail(cycle); linkedList.appendIntoTail(<b>new</b> LinkedList.Node(</font><font>"301"</font><font>)); linkedList.appendIntoTail(<b>new</b> LinkedList.Node(</font><font>"401"</font><font>)); linkedList.appendIntoTail(cycle); </font><font><i>//don't call toString method in case of cyclic linked list, it will throw OutOfMemoryError</i></font><font> </font><font><i>//System.out.println("Linked List : " + linkedList);</i></font><font> <b>if</b>(linkedList.isCyclic()){ System.out.println(</font><font>"Linked List is cyclic as it contains cycles or loop"</font><font>); }<b>else</b>{ System.out.println(</font><font>"LinkedList is not cyclic, no loop or cycle found"</font><font>); } Output: Linked List is cyclic as it contains cycles or loop </font>