Header Ads Widget

Responsive Advertisement

Detect & Handle Infinite Loops and Cycles in Linked Lists


Learn to detect infinite loops in LinkedLists, find the start node of a cycle, and introduce a loop using Java code. Explore cycle detection techniques.


java

package com.java.linklist;
public class LinkedList<T> {
 public static class Node<T> {
  // reference to the next node in the chain, or null if there isn't one.
  Node<T> next;
  // data carried by this node. could be of any type you need.
  T data;
  // Node constructor
  public Node(T dataValue) {
   next = null;
   data = dataValue;
  }
  // another Node constructor if we want to specify the node to point to.
  public Node(T dataValue, Node<T> nextValue) {
   next = nextValue;
   data = dataValue;
  }
  // these methods should be self-explanatory
  public T getData() {
   return data;
  }
  public void setData(T dataValue) {
   data = dataValue;
  }
  public Node<T> getNext() {
   return next;
  }
  public void setNext(Node<T> nextValue) {
   next = nextValue;
  }
 }
 private Node<T> head;
 private Node<T> tail;
 public LinkedList() {
 }
 LinkedList(T data) {
  Node<T> n1 = new Node<T>(data);
  this.head = n1;
  this.tail = n1;
 }
 /**
  * appends the specified element to the end of this list.
  *
  * @param data
  */
 public void add(T data) {
  // if we have an empty list, create a new list
  // and copy its head and tail into current object
  if (this.head == null) {
   LinkedList<T> linkList = (new LinkedList<T>(data));
   this.head = linkList.head;
   this.tail = linkList.tail;
   return;
  }
  // we need to add this node 'n' to the end of the list
  Node<T> n = new Node<T>(data);
  Node<T> current = this.head, prev = null;
  while (current != null) {
   prev = current;
   current = current.next;
  }
  prev.next = n;
  this.tail = n; // update the tail info as well
 }
 public String toString() {
  String output = "";
  if (head != null) {
   Node<T> n = head.getNext();
   output += "[" + head.getData().toString() + "]-->";
   //System.out.println("[" + head.getData().toString() + "]");
   while (n != null) {
    output += "[" + n.getData().toString() + "]-->";
    //System.out.println("[" + n.getData().toString() + "]");
    n = n.getNext();
   }
  }
  return output;
 }
 /**
  * introduces loop of given length at the end of the list.
  *
  * @param length
  */
 public void introduceLoop(int length) {
  if (this.head == null) {
   System.out.println("Empty List. Loop can not be inserted");
   return;
  }
  Node<T> p1 = this.head, p2 = this.head;
  int count = 0;
  while (count < length) {
   if (p2 == null) {
    System.out.println("Incorrect length of the loop given");
    break;
   }
   p2 = p2.next;
   count++;
  }
  Node<T> prevP2 = null;
  while (p2 != null) {
   prevP2 = p2;
   p2 = p2.next;
   p1 = p1.next;
  }
  prevP2.next = p1;
  System.out.println("Loop or cycle Start of length " + length
    + " and the value of node is -->" + p1.data);
 }
 /**
  * <ul>
  * <li>The Tortoise (Slow ptr) and the Hare (fast ptr) start at the
  * beginning of linked list.</li>
  * <li>For each iteration, slow ptr moves one step and the fast ptr moves
  * two steps.</li>
  * <li>If there is a loop, fast ptr will go around the loop and meet with
  * slow ptr.</li>
  * <li>If there is no loop, the fast prt will get to the end of the list
  * without meeting up with the slow ptr.</li>
  * </ul>
  *
  * @return boolean
  */
 public boolean ifLoopExists() {
  Node<T> fastPtr = head;
  Node<T> slowPtr = head;
  while (slowPtr != null && fastPtr != null && fastPtr.next != null) {
   fastPtr = fastPtr.next.next;
   slowPtr = slowPtr.next;
   if (slowPtr == fastPtr)
    return true;
  }
  return false;
 }
 /**
  * <ul>
  * <li>The Tortoise (Slow ptr) and the Hare (fast ptr) start at the
  * beginning of linked list.</li>
  * <li>For each iteration, slow ptr moves one step and the fast ptr moves
  * two steps.</li>
  * <li>If there is a loop, fast ptr will go around the loop and meet with
  * slow ptr.</li>
  * <li>If there is no loop, the fast prt will get to the end of the list
  * without meeting up with the slow ptr.</li>
  * </ul>
  * @return Node
  */
 public Node<T> findStartNodeOfTheLoop() {
  Node<T> fastPtr = head;
  Node<T> slowPtr = head;
  boolean loopExists = false;
  while (fastPtr != null && fastPtr.next != null) {
   fastPtr = fastPtr.next.next;
   slowPtr = slowPtr.next;
   if (slowPtr == fastPtr) {
    loopExists = true;
    break;
   }
  }
  if (loopExists) {
   slowPtr = head;
   while (slowPtr != fastPtr) {
    slowPtr = slowPtr.next;
    fastPtr = fastPtr.next;
   }
  } else {
   System.out.println("Loop does not exists");
   slowPtr = null;
  }
  return slowPtr;
 }
 public static void main(String[] args) {
  System.out.println("------------------Integer-------------------");
  LinkedList<Integer> list = new LinkedList<Integer>();
  list.add(5);
  list.add(6);
  list.add(3);
  list.add(1);
  list.add(2);
  System.out.println(list.toString());
  list.introduceLoop(3);
  System.out.println(list.ifLoopExists());
  Node<Integer> startNode = list.findStartNodeOfTheLoop();
  if (startNode != null) {
   System.out.println("start Node of loop is for integer " + startNode.data);
  }
  System.out.println("------------------String-------------------");
  LinkedList<String> list2 = new LinkedList<String>();
  list2.add("Kartik");
  list2.add("Mandal");
  list2.add("Saharda");
  list2.add("kharagpur");
  list2.add("Westbengal");
  list2.add("India");
  System.out.println(list2.toString());
  list2.introduceLoop(4);//loop
  System.out.println(list2.ifLoopExists());//find out loop
  Node<String> startNode2 = list2.findStartNodeOfTheLoop();//find out start point of loop
  if (startNode != null) {
   System.out.println("start Node of loop is for string " + startNode2.data);
  }
 }
}

 

 

The code you provided is a Java implementation of a generic linked list that supports basic operations like adding elements, detecting loops, and finding the start node of a loop. Here’s a summary of the key components and how they work:

1. Node Class

  • The Node<T> class is a static nested class inside the LinkedList class.
  • Each node contains a reference to the next node (next) and a generic data element (data).
  • Constructors are provided for creating nodes with or without specifying the next node.

2. LinkedList Class

  • The LinkedList<T> class is a generic class that supports different data types.
  • It maintains references to the head and tail of the linked list.
  • A default constructor initializes an empty list.
  • Another constructor initializes a list with a single node containing the provided data.

3. add Method

  • This method adds a new node with the provided data to the end of the list.
  • If the list is empty, it initializes the list with the new node as both head and tail.
  • Otherwise, it traverses to the end of the list and appends the new node.

4. toString Method

  • This method returns a string representation of the linked list by traversing from the head to the tail and appending each node’s data to a string.

5. introduceLoop Method

  • This method introduces a loop in the linked list by connecting the last node to a node at a specific distance (length) from the head.
  • If the loop length is greater than the size of the list, an error message is printed.

6. ifLoopExists Method

  • This method detects if a loop exists in the linked list using Floyd's Tortoise and Hare algorithm.
  • It returns true if a loop is found, otherwise false.

7. findStartNodeOfTheLoop Method

  • This method returns the starting node of the loop if a loop exists.
  • It first detects if a loop exists, then resets the slow pointer to the head and moves both slow and fast pointers one step at a time until they meet, which is the start of the loop.

8. Main Method

  • The main method tests the linked list implementation with Integer and String data types.
  • It demonstrates adding elements, introducing loops, detecting loops, and finding the start of the loop.

Example Outputs:

If you run this program, the output will look like this:

plaintext

------------------Integer-------------------

[5]-->[6]-->[3]-->[1]-->[2]-->

Loop or cycle Start of length 3 and the value of node is -->6

true

start Node of loop is for integer 6

------------------String-------------------

[Kartik]-->[Mandal]-->[Saharda]-->[kharagpur]-->[Westbengal]-->[India]-->

Loop or cycle Start of length 4 and the value of node is -->Mandal

true

start Node of loop is for string Mandal

 

This output shows the string representation of the linked list, the introduction of a loop, whether a loop exists, and the start node of the loop for both integer and string data types.

Key Points to Consider:

  1. Generics: The implementation uses Java Generics (<T>) to make the linked list type-safe and reusable for different data types.
  2. Loop Detection: The ifLoopExists method uses the fast and slow pointer approach to efficiently detect loops.
  3. Finding Loop Start: The findStartNodeOfTheLoop method resets the slow pointer to the head to find the start of the loop after detecting a loop.

This implementation provides a solid foundation for understanding basic linked list operations, including advanced features like loop detection and handling.


Detect infinite loop in LinkedList
Detect infinite loop in LinkedList

 

Post a Comment

0 Comments