美文网首页Java 杂谈互联网科技Spring-Boot
如何用JAVA程序来查找链接列表是否包含循环

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

作者: Java高级架构狮 | 来源:发表于2019-01-28 15:01 被阅读2次

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

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

  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。

/*
 * Java class to represent linked list data structure.
 */
public class LinkedList {
    private Node head;
    public LinkedList() { this.head = new Node("head"); }   
    public Node head() { return head;}
   
    public void appendIntoTail(Node node) {
        Node current = head;
       
        //find last element of LinkedList i.e. tail
        while(current.next() != null){
            current = current.next();
        }
        //appending new node to tail in LinkedList
        current.setNext(node);
    }
   
    /*
     * 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.
     */
    public boolean isCyclic(){
        Node fast = head;
        Node slow = head;
       
        while(fast!= null && fast.next != null){
            fast = fast.next.next;
            slow = slow.next;
           
            //if fast and slow pointers are meeting then LinkedList is cyclic
            if(fast == slow ){
                return true;
            }
        }
        return false;
    }
   
    @Override
    public String toString(){
        StringBuilder sb = new StringBuilder();
        Node current = head.next();
        while(current != null){
           sb.append(current).append("-->");
           current = current.next();
        }
        sb.delete(sb.length() - 3, sb.length()); // to remove --> from last node
       return sb.toString();
    }

    public static class Node {
        private Node next;
        private String data;

        public Node(String data) {
            this.data = data;
        }

        public String data() { return data; }
        public void setData(String data) { this.data = data;}

        public Node next() { return next; }
        public void setNext(Node next) { this.next = next; }

        @Override
        public String toString() {
            return this.data;
        }
    }
}

测试循环的链表

在本节中,我们将使用带有两个链表的Java main方法测试,一个包含循环而另一个不循环。 您甚至可以为isCyclic()方法编写JUnit测试用例,以测试不同位置的循环的不同链表。 这是链表不包含任何循环的第一个测试。

/**
 *
 * 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
 */
public class LinkedListTest {

    public static void main(String args[]) {

        //creating LinkedList with 5 elements including head
        LinkedList linkedList = new LinkedList();
        linkedList.appendIntoTail(new LinkedList.Node("101"));
        linkedList.appendIntoTail(new LinkedList.Node("201"));
        linkedList.appendIntoTail(new LinkedList.Node("301"));
        linkedList.appendIntoTail(new LinkedList.Node("401"));

        System.out.println("Linked List : " + linkedList);

        if(linkedList.isCyclic()){
            System.out.println("Linked List is cyclic as it contains cycles or loop");
        }else{
            System.out.println("LinkedList is not cyclic, no loop or cycle found");
        }    

    } 
   
}

Output:
Linked List : 101-->201-->301-->401
LinkedList is not cyclic, no loop or cycle found

现在让我们改变链表,使其包含循环

//creating LinkedList with 5 elements including head
LinkedList linkedList = new LinkedList();
linkedList.appendIntoTail(new LinkedList.Node("101"));
LinkedList.Node cycle = new LinkedList.Node("201");
linkedList.appendIntoTail(cycle);
linkedList.appendIntoTail(new LinkedList.Node("301"));
linkedList.appendIntoTail(new LinkedList.Node("401"));
linkedList.appendIntoTail(cycle);

//don't call toString method in case of cyclic linked list, it will throw OutOfMemoryError
//System.out.println("Linked List : " + linkedList);

if(linkedList.isCyclic()){
   System.out.println("Linked List is cyclic as it contains cycles or loop");
}else{
   System.out.println("LinkedList is not cyclic, no loop or cycle found");
}    

Output:
Linked List is cyclic as it contains cycles or loop

写在最后:

既然看到这里了,觉得笔者写的还不错的就点个赞,加个关注呗!点关注,不迷路,持续更新!!!

相关文章

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

    查找链表是否包含循环的算法 迭代链表时使用快速和慢速两个指针。快速指针在每次迭代中移动两个节点,而慢速指针移动到一...

  • 上机实验(03次)

    快速排序与折半查找 readme 关于本程序中的EOF说明:由于程序包含标准输入,以EOF结束循环。win下EOF...

  • centos 通过 yum 安装JDK

    首先检索包含java的列表 yum list java* 检索1.8的列表 yum list java-1.8* ...

  • 测试

    lunix指令,如给定文件名,如何查找、如何查找包含某个内容的文件,是否使用awk,sed SQL连接查询 编程:...

  • Java 安装

    1.查找java相关列表 2.安装 devel包里包含其他工具,包括内存监测相关 3.查看版本 4.默认安装路径 ...

  • 使用JDBC链接数据库

    (包含7个步骤) 1.加载jdbc加载程序 在链接数据库之前,先加载链接数据库的驱动程序到JVM通过java.la...

  • python顺序查找&二分查找

    搜索列表中某个元素是否存在通常有两种方法,顺序查找和二分查找。顺序查找用于被查询列表是无序列表的情况;二分查找用于...

  • linux安装java步骤

    1、查找java相关的列表yum search jdk 2、安装jdkyum install java-1.8.0...

  • Python基础(8) - 快速调换字典中的key和value

    如何快速调换字典中的key,value 使用for循环 如何用循环快速生成一个从0到100的列表 使用for循环 ...

  • django框架-7模板-循环、判断、常用标签、过滤器等

    本节内容: 列表,字典,类的实例的使⽤ 循环:迭代显示列表,字典等中的内容 条件判断:判断是否显示该内容,⽐如判断...

网友评论

    本文标题:如何用JAVA程序来查找链接列表是否包含循环

    本文链接:https://www.haomeiwen.com/subject/sfpajqtx.html