Best algorithm to test if a linked list has a cycle

20,437

Solution 1

Have two pointers iterating through the list; make one iterate through at twice the speed of the other, and compare their positions at each step. Off the top of my head, something like:

node* tortoise(begin), * hare(begin);
while(hare = hare->next)
{
    if(hare == tortoise) { throw std::logic_error("There's a cycle"); }
    hare = hare->next;
    if(hare == tortoise) { throw std::logic_error("There's a cycle"); }
    tortoise = tortoise->next;
}

O(n), which is as good as you can get.

Solution 2

Precondition: Keep track of the list size (update the size whenenver a node is added or deleted).

Loop detection:

  1. Keep a counter when traversing the list size.

  2. If the counter exceeds the list size, there is a possible cycle.

Complexity: O(n)

Note: the comparison between the counter and the list size, as well as the update operation of the list size, must be made thread-safe.

Solution 3

Take 2 pointer *p and *q , start traversing the linked list "LL" using both pointers :

1) pointer p will delete previous node each time and pointing to next node.

2) pointer q will go each time in forward direction direction only.

conditions:

1) pointer p is pointing to null and q is pointing to some node : Loop is present

2) both pointer pointing to null: no loop is there

Share:
20,437
cdleary
Author by

cdleary

Updated on July 17, 2020

Comments

  • cdleary
    cdleary almost 4 years

    What's the best (halting) algorithm for determining if a linked list has a cycle in it?

    [Edit] Analysis of asymptotic complexity for both time and space would be sweet so answers can be compared better.

    [Edit] Original question was not addressing nodes with outdegree > 1, but there's some talk about it. That question is more along the lines of "Best algorithm to detect cycles in a directed graph".