Skip to content

Instantly share code, notes, and snippets.

@christianscott
Last active May 28, 2019 04:20
Show Gist options
  • Save christianscott/b93609a8e2bd166a9cf1846bbac2a7a7 to your computer and use it in GitHub Desktop.
Save christianscott/b93609a8e2bd166a9cf1846bbac2a7a7 to your computer and use it in GitHub Desktop.
Linked list cycle detection in Golang
package main
import "fmt"
type listNode struct {
value int
next *listNode
}
func (l *listNode) containsCycle() bool {
slow, fast := l, l.next
for fast != nil && fast.next != nil {
if slow == fast {
return true
}
slow = slow.next
if fast.next != nil {
fast = fast.next.next
}
}
return false
}
package main
import "testing"
func TestDetectCycleSingleNode(t *testing.T) {
l := listNode{value: 0}
if l.containsCycle() {
t.Error("single node should not contain cycle")
}
}
func TestDetectCycleNoCycle(t *testing.T) {
l1 := &listNode{value: 0}
l2 := &listNode{value: 1}
l1.next = l2
if l1.containsCycle() {
t.Error("should not contain cycle")
}
}
func TestDetectCycleSimple(t *testing.T) {
l1 := &listNode{value: 0}
l2 := &listNode{value: 1}
l1.next = l2
l2.next = l1
if !l1.containsCycle() {
t.Error("should contain cycle")
}
}
func TestDetectCycleLoop(t *testing.T) {
l1 := &listNode{value: 0}
l2 := &listNode{value: 1}
l3 := &listNode{value: 2}
l4 := &listNode{value: 3}
l1.next = l2
l2.next = l3
l3.next = l4
l4.next = l1
if !l1.containsCycle() {
t.Error("should contain cycle")
}
}
func TestDetectCycleNineShaped(t *testing.T) {
l1 := &listNode{value: 0}
l2 := &listNode{value: 1}
l3 := &listNode{value: 2}
l4 := &listNode{value: 3}
l1.next = l2
l2.next = l3
l3.next = l4
l4.next = l2
if !l1.containsCycle() {
t.Error("should contain cycle")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment