Skip to content

Commit b36ac50

Browse files
loop detection for linked lists
1 parent 2a9fc3c commit b36ac50

File tree

1 file changed

+114
-0
lines changed
  • Python/chapter02/2.8 - Loop Detection

1 file changed

+114
-0
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#!/usr/bin/python3
2+
import unittest
3+
4+
5+
class Node:
6+
def __init__(self, data, next=None):
7+
self.data = data
8+
self.next = next
9+
10+
11+
class SinglyLinkedList:
12+
def __init__(self):
13+
self.head = None
14+
15+
def addNode(self, data, next=None):
16+
node = Node(data, next)
17+
if not self.head:
18+
self.head = node
19+
else:
20+
temp = self.head
21+
while temp.next:
22+
temp = temp.next
23+
temp.next = node
24+
print('Node added to LL-->', data)
25+
26+
def findNode(self, value):
27+
if not self.head:
28+
print('No list to iterate')
29+
return
30+
31+
temp = self.head
32+
while temp:
33+
if temp.data == value:
34+
return temp
35+
temp = temp.next
36+
return None
37+
38+
def printList(self):
39+
temp = self.head
40+
while temp:
41+
print('->', temp.data)
42+
temp = temp.next
43+
44+
def loopDetection(self):
45+
if not self.head:
46+
print('No list to iterate for loop detection')
47+
return
48+
49+
slow = self.head
50+
fast = self.head
51+
52+
while fast and fast.next:
53+
slow = slow.next
54+
fast = fast.next.next
55+
if slow == fast:
56+
break
57+
58+
if not fast or not fast.next:
59+
return None
60+
61+
slow = self.head
62+
while slow is not fast:
63+
slow = slow.next
64+
fast = fast.next
65+
66+
return fast
67+
68+
69+
class Test(unittest.TestCase):
70+
@classmethod
71+
def setUpClass(cls):
72+
cls.l = SinglyLinkedList()
73+
cls.l.addNode(3)
74+
cls.l.addNode(1)
75+
cls.l.addNode(5)
76+
cls.l.addNode(9)
77+
cls.l.addNode(7)
78+
cls.l.addNode(2)
79+
cls.l.addNode(10)
80+
cls.l.printList()
81+
82+
cls.k = SinglyLinkedList()
83+
cls.k.addNode(1)
84+
cls.k.addNode(10)
85+
cls.k.addNode(15)
86+
cls.k.addNode(16)
87+
cls.k.addNode(1)
88+
cls.k.printList()
89+
90+
@classmethod
91+
def tearDownClass(cls):
92+
pass
93+
94+
def printStatement(self, node):
95+
if node:
96+
print("Start of Loop", hex(id(node)), '-->', node.data)
97+
else:
98+
print('No loop detected')
99+
100+
def test1(self):
101+
node = self.l.findNode(10)
102+
node.next = self.l.findNode(5)
103+
# if uncomment below, will print in infinite
104+
# self.l.printList()
105+
start = self.l.loopDetection()
106+
self.printStatement(start)
107+
108+
def test2(self):
109+
start = self.k.loopDetection()
110+
self.printStatement(start)
111+
112+
113+
if __name__ == '__main__':
114+
unittest.main()

0 commit comments

Comments
 (0)