Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is an efficient algorithm to find whether a singly linked list is circular/cyclic or not? [duplicate]

How can I find whether a singly linked list is circular/cyclic or not? I tried to search but couldn't find a satisfactory solution. If possible, can you provide a pseudo-code or Java-implementation?

For instance:
135714575, where the second 5 is actually the third element of the list.

like image 930
harshit Avatar asked Jul 09 '09 12:07

harshit


People also ask

How do you identify a singly linked list that whether it is circular or not?

To check whether the linked list is circular or not, we will store the header node into some other variable, then traverse the list, if we get null at the next part of any node, then that is not circular, otherwise we will check the next node is same as the stored node or not, if so then that is circular.

What is the best way to detect a cycle in a linked list?

A simple solution is to use hashing. The idea is to traverse the given list and insert each encountered node into a set. If the current node already presents in the set (i.e., it is seen before), that means a cycle is present in the list.

Is binary search is efficient in a singly linked list?

Binary Search is usually fast and efficient for arrays because accessing the middle index between two given indices is easy and fast(Time Complexity O(1)). But memory allocation for the singly linked list is dynamic and non-contiguous, which makes finding the middle element difficult.


1 Answers

The standard answer is to take two iterators at the beginning, increment the first one once, and the second one twice. Check to see if they point to the same object. Then repeat until the one that is incrementing twice either hits the first one or reaches the end.

This algorithm finds any circular link in the list, not just that it's a complete circle.

Pseudo-code (not Java, untested -- off the top of my head)

bool hasCircle(List l) {    Iterator i = l.begin(), j = l.begin();    while (true) {       // increment the iterators, if either is at the end, you're done, no circle       if (i.hasNext())  i = i.next(); else return false;        // second iterator is travelling twice as fast as first       if (j.hasNext())  j = j.next(); else return false;       if (j.hasNext())  j = j.next(); else return false;        // this should be whatever test shows that the two       // iterators are pointing at the same place       if (i.getObject() == j.getObject()) {            return true;       }     } } 
like image 139
Lou Franco Avatar answered Sep 22 '22 01:09

Lou Franco