Detect loop in a linked list

Given a linked list, check if the linked list has loop or not. Below diagram shows a linked list with a loop.

Following are different ways of doing this
Use Hashing:
Traverse the list one by one and keep putting the node addresses in a Hash Table. At any point, if NULL is reached then return false and if next of current node points to any of the previously stored nodes in Hash then return true.



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to detect loop in a linked list
#include <bits/stdc++.h>
using namespace std;
  
/* Link list node */
struct Node {
    int data;
    struct Node* next;
};
  
void push(struct Node** head_ref, int new_data)
{
    /* allocate node */
    struct Node* new_node = new Node;
  
    /* put in the data  */
    new_node->data = new_data;
  
    /* link the old list off the new node */
    new_node->next = (*head_ref);
  
    /* move the head to point to the new node */
    (*head_ref) = new_node;
}
  
// Returns true if there is a loop in linked list
// else returns false.
bool detectLoop(struct Node* h)
{
    unordered_set<Node*> s;
    while (h != NULL) {
        // If this node is already present
        // in hashmap it means there is a cycle
        // (Because you we encountering the
        // node for the second time).
        if (s.find(h) != s.end())
            return true;
  
        // If we are seeing the node for
        // the first time, insert it in hash
        s.insert(h);
  
        h = h->next;
    }
  
    return false;
}
  
/* Driver program to test above function*/
int main()
{
    /* Start with the empty list */
    struct Node* head = NULL;
  
    push(&head, 20);
    push(&head, 4);
    push(&head, 15);
    push(&head, 10);
  
    /* Create a loop for testing */
    head->next->next->next->next = head;
  
    if (detectLoop(head))
        cout << "Loop found";
    else
        cout << "No Loop";
  
    return 0;
}
// This code is contributed by Geetanjali

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to detect loop in a linked list
import java.util.*;
  
public class LinkedList {
  
    static Node head; // head of list
  
    /* Linked list Node*/
    static class Node {
        int data;
        Node next;
        Node(int d)
        {
            data = d;
            next = null;
        }
    }
  
    /* Inserts a new Node at front of the list. */
    static public void push(int new_data)
    {
        /* 1 & 2: Allocate the Node &
                  Put in the data*/
        Node new_node = new Node(new_data);
  
        /* 3. Make next of new Node as head */
        new_node.next = head;
  
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
  
    // Returns true if there is a loop in linked
    // list else returns false.
    static boolean detectLoop(Node h)
    {
        HashSet<Node> s = new HashSet<Node>();
        while (h != null) {
            // If we have already has this node
            // in hashmap it means their is a cycle
            // (Because you we encountering the
            // node second time).
            if (s.contains(h))
                return true;
  
            // If we are seeing the node for
            // the first time, insert it in hash
            s.add(h);
  
            h = h.next;
        }
  
        return false;
    }
  
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        LinkedList llist = new LinkedList();
  
        llist.push(20);
        llist.push(4);
        llist.push(15);
        llist.push(10);
  
        /*Create loop for testing */
        llist.head.next.next.next.next = llist.head;
  
        if (detectLoop(head))
            System.out.println("Loop found");
        else
            System.out.println("No Loop");
    }
}
  
// This code is contributed by Arnav Kr. Mandal.

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to detect loop
# in the linked list
   
# Node class 
class Node:
   
    # Constructor to initialize
    # the node object
    def __init__(self, data):
        self.data = data
        self.next = None
   
class LinkedList:
   
    # Function to initialize head
    def __init__(self):
        self.head = None
   
    # Function to insert a new
    # node at the beginning
    def push(self, new_data):
        new_node = Node(new_data)
        new_node.next = self.head
        self.head = new_node
   
    # Utility function to print it
    # the linked LinkedList
    def printList(self):
        temp = self.head
        while(temp):
            print (temp.data, end =" ")
            temp = temp.next
   
   
    def detectLoop(self):
         s = set()
         temp = self.head
         while (temp):
          
             # If we have already has
             # this node in hashmap it
             # means their is a cycle
             # (Because you we encountering
             # the node second time).
            if (temp in s):
                return True
     
            # If we are seeing the node for
            # the first time, insert it in hash
            s.add(temp)
     
            temp = temp.next
          
     
         return False
   
# Driver program for testing
llist = LinkedList()
llist.push(20)
llist.push(4)
llist.push(15)
llist.push(10)
   
# Create a loop for testing
llist.head.next.next.next.next = llist.head;
  
if( llist.detectLoop()):
    print ("Loop found")
else :
    print ("No Loop ")
  
# This code is contributed by Gitanjali.

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to detect loop in a linked list
using System;
using System.Collections.Generic;
  
class LinkedList {
  
    public Node head; // head of list
  
    /* Linked list Node*/
    public class Node {
        public int data;
        public Node next;
        public Node(int d)
        {
            data = d;
            next = null;
        }
    }
  
    /* Inserts a new Node at front of the list. */
    public void push(int new_data)
    {
        /* 1 & 2: Allocate the Node &
                Put in the data*/
        Node new_node = new Node(new_data);
  
        /* 3. Make next of new Node as head */
        new_node.next = head;
  
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
  
    // Returns true if there is a loop in linked
    // list else returns false.
    public static bool detectLoop(Node h)
    {
        HashSet<Node> s = new HashSet<Node>();
        while (h != null) {
            // If we have already has this node
            // in hashmap it means their is a cycle
            // (Because you we encountering the
            // node second time).
            if (s.Contains(h))
                return true;
  
            // If we are seeing the node for
            // the first time, insert it in hash
            s.Add(h);
  
            h = h.next;
        }
  
        return false;
    }
  
    /* Driver code*/
    public static void Main(String[] args)
    {
        LinkedList llist = new LinkedList();
  
        llist.push(20);
        llist.push(4);
        llist.push(15);
        llist.push(10);
  
        /*Create loop for testing */
        llist.head.next.next.next.next = llist.head;
  
        if (detectLoop(llist.head))
            Console.WriteLine("Loop found");
        else
            Console.WriteLine("No Loop");
    }
}
  
// This code has been contributed by 29AjayKumar

chevron_right


Output:

Loop found

Approach using Mark Visited Nodes: This solution requires modifications to the basic linked list data structure.

  • Have a visited flag with each node. 
  • Traverse the linked list and keep marking visited nodes. 
  • If you see a visited node again then there is a loop. This solution works in O(n) but requires additional information with each node.
  • A variation of this solution that doesn’t require modification to basic data structure can be implemented using a hash, just store the addresses of visited nodes in a hash and if you see an address that already exists in hash then there is a loop
  • .

Floyd’s Cycle-Finding Algorithm: This is the fastest method and has been described below:

  • Traverse linked list using two pointers. 
  • Move one pointer(slow_p) by one and another pointer(fast_p) by two. 
  • If these pointers meet at the same node then there is a loop. If pointers do not meet then linked list doesn’t have a loop
  • .

Below image shows how the detectloop function works in the code :

Implementation of Floyd’s Cycle-Finding Algorithm:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to detect loop in a linked list
#include <bits/stdc++.h>
using namespace std;
  
/* Link list node */
class Node {
public:
    int data;
    Node* next;
};
  
void push(Node** head_ref, int new_data)
{
    /* allocate node */
    Node* new_node = new Node();
  
    /* put in the data */
    new_node->data = new_data;
  
    /* link the old list off the new node */
    new_node->next = (*head_ref);
  
    /* move the head to point to the new node */
    (*head_ref) = new_node;
}
  
int detectloop(Node* list)
{
    Node *slow_p = list, *fast_p = list;
  
    while (slow_p && fast_p && fast_p->next) {
        slow_p = slow_p->next;
        fast_p = fast_p->next->next;
        if (slow_p == fast_p) {
            cout << "Found Loop";
            return 1;
        }
    }
    return 0;
}
  
/* Driver code*/
int main()
{
    /* Start with the empty list */
    Node* head = NULL;
  
    push(&head, 20);
    push(&head, 4);
    push(&head, 15);
    push(&head, 10);
  
    /* Create a loop for testing */
    head->next->next->next->next = head;
    detectloop(head);
  
    return 0;
}
  
// This is code is contributed by rathbhupendra

chevron_right


C

filter_none

edit
close

play_arrow

link
brightness_4
code

// C program to detect loop in a linked list
#include <stdio.h>
#include <stdlib.h>
  
/* Link list node */
struct Node {
    int data;
    struct Node* next;
};
  
void push(struct Node** head_ref, int new_data)
{
    /* allocate node */
    struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
  
    /* put in the data  */
    new_node->data = new_data;
  
    /* link the old list off the new node */
    new_node->next = (*head_ref);
  
    /* move the head to point to the new node */
    (*head_ref) = new_node;
}
  
int detectloop(struct Node* list)
{
    struct Node *slow_p = list, *fast_p = list;
  
    while (slow_p && fast_p && fast_p->next) {
        slow_p = slow_p->next;
        fast_p = fast_p->next->next;
        if (slow_p == fast_p) {
            printf("Found Loop");
            return 1;
        }
    }
    return 0;
}
  
/* Driver program to test above function*/
int main()
{
    /* Start with the empty list */
    struct Node* head = NULL;
  
    push(&head, 20);
    push(&head, 4);
    push(&head, 15);
    push(&head, 10);
  
    /* Create a loop for testing */
    head->next->next->next->next = head;
    detectloop(head);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to detect loop in a linked list
class LinkedList {
    Node head; // head of list
  
    /* Linked list Node*/
    class Node {
        int data;
        Node next;
        Node(int d)
        {
            data = d;
            next = null;
        }
    }
  
    /* Inserts a new Node at front of the list. */
    public void push(int new_data)
    {
        /* 1 & 2: Allocate the Node &
                  Put in the data*/
        Node new_node = new Node(new_data);
  
        /* 3. Make next of new Node as head */
        new_node.next = head;
  
        /* 4. Move the head to point to new Node */
        head = new_node;
    }
  
    int detectLoop()
    {
        Node slow_p = head, fast_p = head;
        while (slow_p != null && fast_p != null && fast_p.next != null) {
            slow_p = slow_p.next;
            fast_p = fast_p.next.next;
            if (slow_p == fast_p) {
                System.out.println("Found loop");
                return 1;
            }
        }
        return 0;
    }
  
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        LinkedList llist = new LinkedList();
  
        llist.push(20);
        llist.push(4);
        llist.push(15);
        llist.push(10);
  
        /*Create loop for testing */
        llist.head.next.next.next.next = llist.head;
  
        llist.detectLoop();
    }
}
/* This code is contributed by Rajat Mishra. */

chevron_right


Python

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to detect loop in the linked list
  
# Node class 
class Node:
  
    # Constructor to initialize the node object
    def __init__(self, data):
        self.data = data
        self.next = None
  
class LinkedList:
  
    # Function to initialize head
    def __init__(self):
        self.head = None
  
    # Function to insert a new node at the beginning
    def push(self, new_data):
        new_node = Node(new_data)
        new_node.next = self.head
        self.head = new_node
  
    # Utility function to print it the linked LinkedList
    def printList(self):
        temp = self.head
        while(temp):
            print temp.data,
            temp = temp.next
  
  
    def detectLoop(self):
        slow_p = self.head
        fast_p = self.head
        while(slow_p and fast_p and fast_p.next):
            slow_p = slow_p.next
            fast_p = fast_p.next.next
            if slow_p == fast_p:
                print "Found Loop"
                return 
  
# Driver program for testing
llist = LinkedList()
llist.push(20)
llist.push(4)
llist.push(15)
llist.push(10)
  
# Create a loop for testing
llist.head.next.next.next.next = llist.head
llist.detectLoop()
  
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to detect loop in a linked list 
using System;
  
public class LinkedList 
    Node head; // head of list 
  
    /* Linked list Node*/
    public class Node 
    
        public int data; 
        public Node next; 
        public Node(int d) 
        
            data = d; 
            next = null
        
    
  
    /* Inserts a new Node at front of the list. */
    public void push(int new_data) 
    
        /* 1 & 2: Allocate the Node & 
                Put in the data*/
        Node new_node = new Node(new_data); 
  
        /* 3. Make next of new Node as head */
        new_node.next = head; 
  
        /* 4. Move the head to point to new Node */
        head = new_node; 
    
  
    int detectLoop() 
    
        Node slow_p = head, fast_p = head; 
        while (slow_p != null && fast_p != null &&
                                fast_p.next != null)
        
            slow_p = slow_p.next; 
            fast_p = fast_p.next.next; 
            if (slow_p == fast_p)
            
                Console.WriteLine("Found loop"); 
                return 1; 
            
        
        return 0; 
    
  
    /* Driver code */
    public static void Main(String []args) 
    
        LinkedList llist = new LinkedList(); 
  
        llist.push(20); 
        llist.push(4); 
        llist.push(15); 
        llist.push(10); 
  
        /*Create loop for testing */
        llist.head.next.next.next.next = llist.head; 
  
        llist.detectLoop(); 
    
  
// This code is contributed by Princi Singh

chevron_right


Output:

Found Loop

Time Complexity: O(n)
Auxiliary Space: O(1)

How does above algorithm work?
Please See : How does Floyd’s slow and fast pointers approach work?

References:
http://en.wikipedia.org/wiki/Cycle_detection
http://ostermiller.org/find_loop_singly_linked_list.html

Marking visited nodes without modifying the linked list data structure
In this method, a temporary node is created. The next pointer of each node that is traversed is made to point to this temporary node. This way we are using the next pointer of a node as a flag to indicate whether the node has been traversed or not. Every node is checked to see if the next is pointing to a temporary node or not. In the case of the first node of the loop, the second time we traverse it this condition will be true, hence we find that loop exists. If we come across a node that points to null then loop doesn’t exist.
The code runs in O(n) time complexity and uses constant memory space.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to return first node of loop
#include <bits/stdc++.h>
using namespace std;
  
struct Node {
    int key;
    struct Node* next;
};
  
Node* newNode(int key)
{
    Node* temp = new Node;
    temp->key = key;
    temp->next = NULL;
    return temp;
}
  
// A utility function to print a linked list
void printList(Node* head)
{
    while (head != NULL) {
        cout << head->key << " ";
        head = head->next;
    }
    cout << endl;
}
  
// Function to detect first node of loop
// in a linked list that may contain loop
bool detectLoop(Node* head)
{
  
    // Create a temporary node
    Node* temp = new Node;
    while (head != NULL) {
  
        // This condition is for the case
        // when there is no loop
        if (head->next == NULL) {
            return false;
        }
  
        // Check if next is already
        // pointing to temp
        if (head->next == temp) {
            return true;
        }
  
        // Store the pointer to the next node
        // in order to get to it in the next step
        Node* nex = head->next;
  
        // Make next point to temp
        head->next = temp;
  
        // Get to the next node in the list
        head = nex;
    }
  
    return false;
}
  
/* Driver program to test above function*/
int main()
{
    Node* head = newNode(1);
    head->next = newNode(2);
    head->next->next = newNode(3);
    head->next->next->next = newNode(4);
    head->next->next->next->next = newNode(5);
  
    /* Create a loop for testing(5 is pointing to 3) */
    head->next->next->next->next->next = head->next->next;
  
    bool found = detectLoop(head);
    if (found)
        cout << "Loop Found";
    else
        cout << "No Loop";
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to return first node of loop
class GFG {
  
    static class Node {
        int key;
        Node next;
    };
  
    static Node newNode(int key)
    {
        Node temp = new Node();
        temp.key = key;
        temp.next = null;
        return temp;
    }
  
    // A utility function to print a linked list
    static void printList(Node head)
    {
        while (head != null) {
            System.out.print(head.key + " ");
            head = head.next;
        }
        System.out.println();
    }
  
    // Function to detect first node of loop
    // in a linked list that may contain loop
    static boolean detectLoop(Node head)
    {
  
        // Create a temporary node
        Node temp = new Node();
        while (head != null) {
  
            // This condition is for the case
            // when there is no loop
            if (head.next == null) {
                return false;
            }
  
            // Check if next is already
            // pointing to temp
            if (head.next == temp) {
                return true;
            }
  
            // Store the pointer to the next node
            // in order to get to it in the next step
            Node nex = head.next;
  
            // Make next point to temp
            head.next = temp;
  
            // Get to the next node in the list
            head = nex;
        }
  
        return false;
    }
  
    // Driver code
    public static void main(String args[])
    {
        Node head = newNode(1);
        head.next = newNode(2);
        head.next.next = newNode(3);
        head.next.next.next = newNode(4);
        head.next.next.next.next = newNode(5);
  
        // Create a loop for testing(5 is pointing to 3) /
        head.next.next.next.next.next = head.next.next;
  
        boolean found = detectLoop(head);
        if (found)
            System.out.println("Loop Found");
        else
            System.out.println("No Loop");
    }
}
  
// This code is contributed by Arnab Kundu

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to return first node of loop 
  
# A binary tree node has data, pointer to 
# left child and a pointer to right child 
# Helper function that allocates a new node 
# with the given data and None left and 
# right pointers 
class newNode:
    def __init__(self, key):
        self.key= key
        self.left = None
        self.right = None
  
# A utility function to pra linked list 
def printList(head):
    while (head != None):
        print(head.key, end = " ")
        head = head.next
      
    print()
  
# Function to detect first node of loop 
# in a linked list that may contain loop 
def detectLoop( head):
  
    # Create a temporary node
    temp = ""
    while (head != None):
          
        # This condition is for the case
        # when there is no loop
        if (head.next == None):
            return False
              
        # Check if next is already
        # pointing to temp
        if (head.next == temp):
            return True
  
        # Store the pointer to the next node
        # in order to get to it in the next step
        nex = head.next
  
        # Make next poto temp
        head.next = temp
  
        # Get to the next node in the list
        head = nex
  
    return False
  
# Driver Code
head = newNode(1
head.next = newNode(2
head.next.next = newNode(3
head.next.next.next = newNode(4
head.next.next.next.next = newNode(5
  
# Create a loop for testing(5 is pointing to 3)
head.next.next.next.next.next = head.next.next
  
found = detectLoop(head) 
if (found):
    print("Loop Found")
else:
    print("No Loop")
  
# This code is contributed by SHUBHAMSINGH10

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to return first node of loop
using System;
public class GFG {
  
    public class Node {
        public int key;
        public Node next;
    };
  
    static Node newNode(int key)
    {
        Node temp = new Node();
        temp.key = key;
        temp.next = null;
        return temp;
    }
  
    // A utility function to print a linked list
    static void printList(Node head)
    {
        while (head != null) {
            Console.Write(head.key + " ");
            head = head.next;
        }
        Console.WriteLine();
    }
  
    // Function to detect first node of loop
    // in a linked list that may contain loop
    static Boolean detectLoop(Node head)
    {
  
        // Create a temporary node
        Node temp = new Node();
        while (head != null) {
  
            // This condition is for the case
            // when there is no loop
            if (head.next == null) {
                return false;
            }
  
            // Check if next is already
            // pointing to temp
            if (head.next == temp) {
                return true;
            }
  
            // Store the pointer to the next node
            // in order to get to it in the next step
            Node nex = head.next;
  
            // Make next point to temp
            head.next = temp;
  
            // Get to the next node in the list
            head = nex;
        }
  
        return false;
    }
  
    // Driver code
    public static void Main(String[] args)
    {
        Node head = newNode(1);
        head.next = newNode(2);
        head.next.next = newNode(3);
        head.next.next.next = newNode(4);
        head.next.next.next.next = newNode(5);
  
        // Create a loop for testing(5 is pointing to 3) /
        head.next.next.next.next.next = head.next.next;
  
        Boolean found = detectLoop(head);
        if (found)
            Console.WriteLine("Loop Found");
        else
            Console.WriteLine("No Loop");
    }
}
  
// This code is contributed by Princi Singh

chevron_right


Output:

Loop Found

Time Complexity: O(n)
Auxiliary Space: O(1)

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



My Personal Notes arrow_drop_up