Open In App

Floyd’s Cycle Finding Algorithm

Floyd’s cycle finding algorithm or Hare-Tortoise algorithm is a pointer algorithm that uses only two pointers, moving through the sequence at different speeds. This algorithm is used to find a loop in a linked list. It uses two pointers one moving twice as fast as the other one. The faster one is called the fast pointer and the other one is called the slow pointer.

How Does Floyd’s Cycle Finding Algorithm Works?



While traversing the linked list one of these things will occur-

Example:



Pseudocode:

Below is the C++ program to implement the above approach:




// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
class Node {
public:
    int data;
    Node* next;
 
    Node(int data)
    {
        this->data = data;
        next = NULL;
    }
};
 
// initialize a new head for the linked list
Node* head = NULL;
class Linkedlist {
public:
    // insert new value at the start
    void insert(int value)
    {
        Node* newNode = new Node(value);
        if (head == NULL)
            head = newNode;
        else {
            newNode->next = head;
            head = newNode;
        }
    }
 
    // detect if there is a loop
    // in the linked list
    bool detectLoop()
    {
        Node *slowPointer = head,
             *fastPointer = head;
 
        while (slowPointer != NULL
               && fastPointer != NULL
               && fastPointer->next != NULL) {
            slowPointer = slowPointer->next;
            fastPointer = fastPointer->next->next;
            if (slowPointer == fastPointer)
                return 1;
        }
 
        return 0;
    }
};
 
int main()
{
    Linkedlist l1;
    // inserting new values
    l1.insert(10);
    l1.insert(20);
    l1.insert(30);
    l1.insert(40);
    l1.insert(50);
 
    // adding a loop for the sake
    // of this example
    Node* temp = head;
    while (temp->next != NULL)
        temp = temp->next;
 
    temp->next = head;
 
    // loop added;
 
    if (l1.detectLoop())
        cout << "Loop exists in the"
             << " Linked List" << endl;
    else
        cout << "Loop does not exists "
             << "in the Linked List" << endl;
 
    return 0;
}




// Java program to implement
// the above approach
 
import java.util.*;
 
class GFG{
 
static class Node {
    int data;
    Node next;
 
    Node(int data)
    {
        this.data = data;
        next = null;
    }
};
 
// initialize a new head for the linked list
static Node head = null;
static class Linkedlist {
    // insert new value at the start
    void insert(int value)
    {
        Node newNode = new Node(value);
        if (head == null)
            head = newNode;
        else {
            newNode.next = head;
            head = newNode;
        }
    }
 
    // detect if there is a loop
    // in the linked list
    boolean detectLoop()
    {
        Node slowPointer = head,
             fastPointer = head;
 
        while (slowPointer != null
               && fastPointer != null
               && fastPointer.next != null) {
            slowPointer = slowPointer.next;
            fastPointer = fastPointer.next.next;
            if (slowPointer == fastPointer)
                return true;
        }
 
    return false;
    }
}
 
public static void main(String[] args)
{
    Linkedlist l1 = new Linkedlist();
    // inserting new values
    l1.insert(10);
    l1.insert(20);
    l1.insert(30);
    l1.insert(40);
    l1.insert(50);
 
    // adding a loop for the sake
    // of this example
    Node temp = head;
    while (temp.next != null)
        temp = temp.next;
 
    temp.next = head;
 
    // loop added;
 
    if (l1.detectLoop())
        System.out.print("Loop exists in the"
            + " Linked List" +"\n");
    else
        System.out.print("Loop does not exists "
            + "in the Linked List" +"\n");
 
}
}
 
// This code is contributed by 29AjayKumar




# Python code for the above approach
class Node:
    def __init__(self, d):
        self.data = d
        self.next = None
 
# initialize a new head for the linked list
head = None
 
# detect if there is a loop
# in the linked list
def detectLoop(head):
    slowPointer = head
    fastPointer = head
 
    while (slowPointer != None
           and fastPointer != None
           and fastPointer.next != None):
        slowPointer = slowPointer.next
        fastPointer = fastPointer.next.next
        if (slowPointer == fastPointer):
            return 1
 
    return 0
 
# inserting new values
head = Node(10)
head.next = Node(20)
head.next.next = Node(30)
head.next.next.next = Node(40)
head.next.next.next.next = Node(50)
 
# adding a loop for the sake
# of this example
temp = head
while (temp.next != None):
    temp = temp.next
 
temp.next = head
 
# loop added;
if (detectLoop(head)):
    print("Loop exists in the Linked List")
else:
    print("Loop does not exists in the Linked List")
 
# This code is contributed by Saurabh Jaiswal




// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
public class GFG {
 
  public class Node {
    public int data;
    public Node next;
 
    public Node(int data) {
      this.data = data;
      next = null;
    }
  };
 
  // initialize a new head for the linked list
  static Node head = null;
 
  public class Linkedlist
  {
 
    // insert new value at the start
    public void insert(int value) {
      Node newNode = new Node(value);
      if (head == null)
        head = newNode;
      else {
        newNode.next = head;
        head = newNode;
      }
    }
 
    // detect if there is a loop
    // in the linked list
    public bool detectLoop() {
      Node slowPointer = head, fastPointer = head;
 
      while (slowPointer != null && fastPointer != null &&
             fastPointer.next != null)
      {
        slowPointer = slowPointer.next;
        fastPointer = fastPointer.next.next;
        if (slowPointer == fastPointer)
          return true;
      }
 
      return false;
    }
  }
 
  public static void Main(String[] args) {
    Linkedlist l1 = new Linkedlist();
    // inserting new values
    l1.insert(10);
    l1.insert(20);
    l1.insert(30);
    l1.insert(40);
    l1.insert(50);
 
    // adding a loop for the sake
    // of this example
    Node temp = head;
    while (temp.next != null)
      temp = temp.next;
 
    temp.next = head;
 
    // loop added;
    if (l1.detectLoop())
      Console.Write("Loop exists in the" + " Linked List" + "\n");
    else
      Console.Write("Loop does not exists " + "in the Linked List" + "\n");
 
  }
}
 
// This code is contributed by umadevi9616




<script>
        // JavaScript code for the above approach
        class Node
        {
            constructor(d)
            {
                this.data = d;
                this.next = null;
            }
        }
 
        // initialize a new head for the linked list
        let head = null;
 
        // detect if there is a loop
        // in the linked list
        function detectLoop(head) {
            let slowPointer = head;
            let fastPointer = head;
 
            while (slowPointer != null
                && fastPointer != null
                && fastPointer.next != null) {
                slowPointer = slowPointer.next;
                fastPointer = fastPointer.next.next;
                if (slowPointer == fastPointer)
                    return 1;
            }
 
            return 0;
        }
 
        // inserting new values
        head = new Node(10);
        head.next = new Node(20);
        head.next.next = new Node(30);
        head.next.next.next = new Node(40);
        head.next.next.next.next = new Node(50);
 
        // adding a loop for the sake
        // of this example
        let temp = head;
        while (temp.next != null)
            temp = temp.next;
 
        temp.next = head;
 
        // loop added;
        if (detectLoop(head))
            document.write("Loop exists in the Linked List" + "<br>");
        else
            document.write("Loop does not exists in the Linked List" + "<br>");
 
       // This code is contributed by Potta Lokesh
    </script>

Output
Loop exists in the Linked List

Time complexity: O(n), as the loop is traversed once. 
Auxiliary Space: O(1), only two pointers are used therefore constant space complexity.

Why Does Floyd’s Algorithm Works?

Let us consider an example:

X = Distance between the head(starting) to the loop starting point.

Y = Distance between the loop starting point and the first meeting point of both the pointers.

C = The distance of the loop

The slow pointer has traveled X + Y + s * C distance, where s is any positive constant number.

The fast pointer has traveled X + Y + f * C distance, where f is any positive constant number.

 X + Y + f * C = 2 * (X + Y + s * C)

X + Y = f * C – 2 * s * C

We can say that,

f * C – 2 * s * C = (some integer) * C

                         = K * C

Thus,

X + Y = K * C       – ( 1 )

X = K * C – Y        – ( 2 )

Where K is some positive constant.    

Below is the C++ program to implement the above approach-




// C++ program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
 
class Node {
public:
    int data;
    Node* next;
 
    Node(int data)
    {
        this->data = data;
        next = NULL;
    }
};
 
// initialize a new head
// for the linked list
Node* head = NULL;
class Linkedlist {
public:
    // insert new value at the start
    void insert(int value)
    {
        Node* newNode = new Node(value);
        if (head == NULL)
            head = newNode;
        else {
            newNode->next = head;
            head = newNode;
        }
    }
 
    // detect if there is a loop
    // in the linked list
    Node* detectLoop()
    {
        //If link list is empty, there are no loop.
        //If only one element is found in link list, there are no loop.
        if(head==NULL || head->next==NULL){
            return NULL;
        }
       
        Node *slowPointer = head, *fastPointer = head;
 
        while (slowPointer != NULL && fastPointer != NULL
               && fastPointer->next != NULL) {
            slowPointer = slowPointer->next;
            fastPointer = fastPointer->next->next;
            if (slowPointer == fastPointer)
                break;
        }
 
        // if no loop exists
        if (slowPointer != fastPointer)
            return NULL;
 
        // reset slow pointer to head
        // and traverse again
        slowPointer = head;
        while (slowPointer != fastPointer) {
            slowPointer = slowPointer->next;
            fastPointer = fastPointer->next;
        }
 
        return slowPointer;
    }
};
 
int main()
{
    Linkedlist l1;
    // inserting new values
    l1.insert(10);
    l1.insert(20);
    l1.insert(30);
    l1.insert(40);
    l1.insert(50);
 
    // adding a loop for the sake
    // of this example
    Node* temp = head;
    while (temp->next != NULL)
        temp = temp->next;
    // loop added;
    temp->next = head;
 
    Node* loopStart = l1.detectLoop();
    if (loopStart == NULL)
        cout << "Loop does not exists" << endl;
    else {
        cout << "Loop does exists and starts from "
             << loopStart->data << endl;
    }
 
    return 0;
}




// Java program to implement
// the above approach
import java.util.*;
public class GFG {
 
    static class Node {
        int data;
        Node next;
 
        Node(int data)
        {
            this.data = data;
            next = null;
        }
    }
 
    // initialize a new head for the linked list
    static Node head = null;
    static class Linkedlist {
        // insert new value at the start
        void insert(int value)
        {
            Node newNode = new Node(value);
            if (head == null)
                head = newNode;
            else {
                newNode.next = head;
                head = newNode;
            }
        }
 
        // detect if there is a loop
        // in the linked list
        public Node detectLoop()
        {
            Node slowPointer = head, fastPointer = head;
 
            while (slowPointer != null
                   && fastPointer != null
                   && fastPointer.next != null) {
                slowPointer = slowPointer.next;
                fastPointer = fastPointer.next.next;
                if (slowPointer == fastPointer)
                    break;
            }
 
            // if no loop exists
            if (slowPointer != fastPointer)
                return null;
 
            // reset slow pointer to head
            // and traverse again
            slowPointer = head;
            while (slowPointer != fastPointer) {
                slowPointer = slowPointer.next;
                fastPointer = fastPointer.next;
            }
 
            return slowPointer;
        }
    }
 
    public static void main(String[] args)
    {
        Linkedlist l1 = new Linkedlist();
        // inserting new values
        l1.insert(10);
        l1.insert(20);
        l1.insert(30);
        l1.insert(40);
        l1.insert(50);
 
        // adding a loop for the sake
        // of this example
 
        Node temp = head;
        while (temp.next != null)
            temp = temp.next;
 
        temp.next = head;
 
        // loop added;
 
        Node loopStart = l1.detectLoop();
        if (loopStart == null)
            System.out.println("Loop does not exists");
        else {
            System.out.println(
                "Loop does exists and starts from "
                + loopStart.data);
        }
    }
}
 
// This code is contributed by jana_sayantan.




# Python code for the above approach
class Node:
    def __init__(self, d):
        self.data = d
        self.next = None
  
# initialize a new head for the linked list
head = None
  
# detect if there is a loop
# in the linked list
def detectLoop(head):
    slowPointer = head
    fastPointer = head
  
    while (slowPointer != None
           and fastPointer != None
           and fastPointer.next != None):
        slowPointer = slowPointer.next
        fastPointer = fastPointer.next.next
        if (slowPointer == fastPointer):
            break
 
    # if no loop exists
    if (slowPointer != fastPointer):
            return None
     
    # reset slow pointer to head
    # and traverse again
    slowPointer = head
    while (slowPointer != fastPointer):
      slowPointer = slowPointer.next
      fastPointer = fastPointer.next
     
    return slowPointer
   
  
# inserting new values
head = Node(50)
head.next = Node(40)
head.next.next = Node(30)
head.next.next.next = Node(20)
head.next.next.next.next = Node(10)
  
# adding a loop for the sake
# of this example
temp = head
while (temp.next != None):
    temp = temp.next
# loop added
temp.next = head
 
loopStart = detectLoop(head)
if (loopStart == None):
    print("Loop does not exists")
else:
    print(f"Loop does exists and starts from {loopStart.data}")
  
# This code is contributed by Priyank Namdeo




// C# program to implement the above approach
 
using System;
public class GFG
{
 
    public class Node
    {
        public int data;
        public Node next;
 
        public Node(int data)
        {
            this.data = data;
            next = null;
        }
    }
 
    // initialize a new head for the linked list
    static Node head = null;
    public class Linkedlist
    {
        // insert new value at the start
        public void insert(int value)
        {
            Node newNode = new Node(value);
            if (head == null)
                head = newNode;
            else
            {
                newNode.next = head;
                head = newNode;
            }
        }
 
        // detect if there is a loop
        // in the linked list
        public Node detectLoop()
        {
            Node slowPointer = head, fastPointer = head;
 
            while (slowPointer != null
                   && fastPointer != null
                   && fastPointer.next != null)
            {
                slowPointer = slowPointer.next;
                fastPointer = fastPointer.next.next;
                if (slowPointer == fastPointer)
                    break;
            }
 
            // if no loop exists
            if (slowPointer != fastPointer)
                return null;
 
            // reset slow pointer to head
            // and traverse again
            slowPointer = head;
            while (slowPointer != fastPointer)
            {
                slowPointer = slowPointer.next;
                fastPointer = fastPointer.next;
            }
 
            return slowPointer;
        }
    }
 
    public static void Main()
    {
        Linkedlist l1 = new Linkedlist();
        // inserting new values
        l1.insert(10);
        l1.insert(20);
        l1.insert(30);
        l1.insert(40);
        l1.insert(50);
 
        // adding a loop for the sake
        // of this example
 
        Node temp = head;
        while (temp.next != null)
            temp = temp.next;
 
        temp.next = head;
 
        // loop added;
 
        Node loopStart = l1.detectLoop();
        if (loopStart == null)
            Console.WriteLine("Loop does not exists");
        else
        {
            Console.WriteLine(
                "Loop does exists and starts from "
                + loopStart.data);
        }
    }
}
 
// This code is contributed by Saurabh Jaiswal




// JavaScript code for the above approach
 
class Node
{
    constructor(d)
    {
        this.data = d;
        this.next = null;
    }
}
 
// initialize a new head for the linked list
let head = null;
 
function detectLoop(head) {
    let slowPointer = head, fastPointer = head;
     
    while(slowPointer!=null && fastPointer!=null && fastPointer.next!=null){
        slowPointer = slowPointer.next;
        fastPointer = fastPointer.next.next;
        if(slowPointer==fastPointer){
            break;
        }
    }
     
    // if no loop exists
    if(slowPointer!=fastPointer){
        return null;
    }
     
    // reset slow pointer to head and traverse again
    slowPointer = head;
    while(slowPointer!=fastPointer){
        slowPointer = slowPointer.next;
        fastPointer = fastPointer.next;
    }
     
    return slowPointer;
}
 
// inserting new values
head = new Node(50);
head.next = new Node(40);
head.next.next = new Node(30);
head.next.next.next = new Node(20);
head.next.next.next.next = new Node(10);
 
// adding a loop for the sake
// of this example
let temp = head;
while (temp.next != null)
    temp = temp.next;
 
temp.next = head;
 
// loop added;
let loopStart = detectLoop(head);
if (loopStart==null)
console.log("Loop does not exists" + "<br>");
else
    console.log("Loop does exists and starts from " + loopStart.data);
 
// This code is contributed by lokeshmvs21.

Output
Loop does exists and starts from 50

Time complexity: O(n), as we have traversed the loop once and then traveled X distance. 
Auxiliary space: O(1), as only pointers are used therefore constant space complexity.


Article Tags :