转载

如何用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>
原文  https://www.jdon.com/51591
正文到此结束
Loading...