How to detect cycle in a Singly linkedlist
Introduction
As we know each element in a linked list is linked to the next element using a pointer called a next pointer. There’s a chance that next pointer of last node(tail) can point to one of the previous node except the head of linkedlist. By principle tail of a Singly linkedlist should point to a null node.
As we can see in the above illustration a cycle is being formed starting from node-3 to node-8.
Why is cycle in a Singly Linkedlist not good?
Let’s revisit the above illustration of cycle in linkedlist again. As we know, a linkedlist is traversed linearly(one after the other). Let’s see what happens when try to traverse this linkedlist:
- We start from
node-1as it is the head of linkedlist. - Then we go to
node-2then tonode-3then tonode-4then tonode-5then tonode-6then tonode-7then tonode-8. - Everything is pretty normal till we traverse to
node-8when we go tonode-8's nextwe again reachnode-3. As node-8’s next is pointing to node-3. - From
node-3the whole traversal cycle begins again(node-3tonode-4tonode-5tonode-6tonode-7tonode-8). Now we’re pretty much stuck in a infinite loop situation.
So, the problem with having a cycle in linkedlist is iterating over the same nodes again and again infinitely.
How to detect cycle in a linkedlist?
We can detect cycle in a linkedlist by using a method called Hare and Tortoise also called Fast and Slow Pointer technique.
In
Hare and TortoiseorFast and Slow Pointertechnique we take two pointershare or fastandtortoise or slowrespectively. We move the hare pointer two nodes ahead and tortoise one node ahead every iteration. If there’s a cycle in linkedlis then there will be a time whenhare or fastandtortoise or slowpoint to the same node. When that happens we know for sure that there’s a cycle in linkedlist. If there’s no cycle in linkedlist thenhare or fastandtortoise or slowwill always keep moving forward and never converge at a node.
In order to detect a loop we will write a function which takes in head of a linkedlist and returns true if there’s a cycle and false otherwise.
func HasCycle(head *Node) bool {
// initialize hare and tortoise same as the head node
hare, tortoise := head
// iterate over linkedlist till hare reaches the end of linkedlist
for tortoise != nil && hare != nil && hare.next != nil {
// make tortoise move one node ahead
tortoise = tortoise.next
// make hare move two nodes ahead
hare = hare.next.next
// tortoise and hare are at the same node return true
if tortoise == hare {
return true
}
}
// if we have traversed till emd of linkedlist then return false
return false
}
Let’s see the dry run of this function with the illsutration we’re working with:
Key takeaways from above code:
- We take head of linkedlist as input and iterate over linkedlist using the head.
- We initialize
hareandtortoiseas the head. This means that initially both hare and tortoise are at the same position.- We iterate till we reach the end of linkedlist.
- We make tortoise move one node ahead.
- We make hare move two nodes ahead.
- If hare and tortoise are at the same node we return true.
- Otherwise if we reach end of linkedlist it means there’s no cycle hence we return false
Closing words
In the next blogs we’ll see how to find starting node of a cycle in linkedlist.
I hope you enjoyed reading this blog and it added some value.