Skip to content

Commit

Permalink
Contains loops.py add (TheAlgorithms#2442)
Browse files Browse the repository at this point in the history
* added an algorithm which checks a linked list for loops and returns true if one is found

* added doctests and clarified meaning of loop

* Define Node.__iter__()

* Update and rename has_loop.py to has_duplicate_data.py

* Update has_duplicate_data.py

* Update has_duplicate_data.py

* Update and rename has_duplicate_data.py to has_loop.py

* Update has_loop.py

Co-authored-by: Christian Clauss <cclauss@me.com>
  • Loading branch information
2 people authored and stokhos committed Jan 3, 2021
1 parent 71faa33 commit 5cb8760
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions data_structures/linked_list/has_loop.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
from typing import Any


class ContainsLoopError(Exception):
pass


class Node:
def __init__(self, data: Any) -> None:
self.data = data
self.next_node = None

def __iter__(self):
node = self
visited = []
while node:
if node in visited:
raise ContainsLoopError
visited.append(node)
yield node.data
node = node.next_node

@property
def has_loop(self) -> bool:
"""
A loop is when the exact same Node appears more than once in a linked list.
>>> root_node = Node(1)
>>> root_node.next_node = Node(2)
>>> root_node.next_node.next_node = Node(3)
>>> root_node.next_node.next_node.next_node = Node(4)
>>> root_node.has_loop
False
>>> root_node.next_node.next_node.next_node = root_node.next_node
>>> root_node.has_loop
True
"""
try:
list(self)
return False
except ContainsLoopError:
return True


if __name__ == "__main__":
root_node = Node(1)
root_node.next_node = Node(2)
root_node.next_node.next_node = Node(3)
root_node.next_node.next_node.next_node = Node(4)
print(root_node.has_loop) # False
root_node.next_node.next_node.next_node = root_node.next_node
print(root_node.has_loop) # True

root_node = Node(5)
root_node.next_node = Node(6)
root_node.next_node.next_node = Node(5)
root_node.next_node.next_node.next_node = Node(6)
print(root_node.has_loop) # False

root_node = Node(1)
print(root_node.has_loop) # False

0 comments on commit 5cb8760

Please sign in to comment.