如何用JAVA程序来查找链接列表是否包含循环

栏目: Java · 发布时间: 7年前

内容简介:查找链表是否包含循环的算法迭代链表时使用快速和慢速两个指针。快速指针在每次迭代中移动两个节点,而慢速指针移动到一个节点。如果链表包含循环或循环,那么在迭代过程中,快指针和慢指针都会在某个点上相遇。如果它们不相交,并且快速或慢速将指向空,那么链表就不是循环的,它不包含任何循环。这是精确的算法1)使用快速和慢速两个指针

查找链表是否包含循环的算法

迭代链表时使用快速和慢速两个指针。快速指针在每次迭代中移动两个节点,而慢速指针移动到一个节点。如果链表包含循环或循环,那么在迭代过程中,快指针和慢指针都会在某个点上相遇。如果它们不相交,并且快速或慢速将指向空,那么链表就不是循环的,它不包含任何循环。这是精确的算法

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>

以上所述就是小编给大家介绍的《如何用JAVA程序来查找链接列表是否包含循环》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Realm of Racket

Realm of Racket

Matthias Felleisen、Conrad Barski M.D.、David Van Horn、Eight Students Northeastern University of / No Starch Press / 2013-6-25 / USD 39.95

Racket is the noble descendant of Lisp, a programming language renowned for its elegance and power. But while Racket retains the functional goodness of Lisp that makes programming purists drool, it wa......一起来看看 《Realm of Racket》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

MD5 加密
MD5 加密

MD5 加密工具

SHA 加密
SHA 加密

SHA 加密工具