forked from kelvins/algorithms-and-data-structures
-
Notifications
You must be signed in to change notification settings - Fork 0
/
circular_linked_list.py
123 lines (102 loc) · 3.32 KB
/
circular_linked_list.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
""" Implementation of a circular linked list in Python """
import unittest
class Node:
def __init__(self, value):
self.__value = value
self.next = None
def get_value(self):
return self.__value
class CircularlyLinkedList:
def __init__(self):
self.__head = None
self.__tail = None
self.__size = 0
def __len__(self):
return self.__size
def __iter__(self):
node = self.__head
while node:
yield node
if node == self.__tail:
break
node = node.next
def __str__(self):
items = ""
for item in self.__iter__():
items += str(item.get_value()) + " "
return items
def __repr__(self):
return self.__str__()
def insert(self, value):
new_node = Node(value)
new_node.next = self.__head
self.__head = new_node
if self.__size == 0:
self.__tail = new_node
self.__tail.next = self.__head
self.__size += 1
def append(self, value):
new_node = Node(value)
if self.__size == 0:
self.__head = new_node
else:
self.__tail.next = new_node
self.__tail = new_node
self.__tail.next = self.__head
self.__size += 1
def remove(self, value):
prev_node = None
found = False
for curr_node in self.__iter__():
if value == curr_node.get_value():
found = True
if prev_node:
prev_node.next = curr_node.next
if curr_node == self.__tail:
self.__tail = prev_node
else:
if self.__size == 1:
self.__init__()
break
else:
self.__head = curr_node.next
self.__tail.next = self.__head
curr_node = None
self.__size -= 1
prev_node = curr_node
if not found:
raise ValueError(str(value) + " not found in list")
class TestCircularlyLinkedList(unittest.TestCase):
def setUp(self):
self.list = CircularlyLinkedList()
def test_insert(self):
self.list.insert(1)
self.list.insert(2)
self.assertEqual("2 1 ", str(self.list))
def test_append(self):
self.list.append(1)
self.list.append(2)
self.assertEqual("1 2 ", str(self.list))
def test_remove(self):
self.list.insert(1)
self.list.insert(2)
self.list.append(3)
self.list.append(4)
self.list.remove(3)
self.assertEqual("2 1 4 ", str(self.list))
self.list.remove(2)
self.assertEqual("1 4 ", str(self.list))
self.list.remove(4)
self.assertEqual("1 ", str(self.list))
self.list.remove(1)
self.assertEqual("", str(self.list))
self.assertRaises(ValueError, self.list.remove, 9)
def test_size(self):
self.list.insert(1)
self.list.append(2)
self.list.insert(3)
self.list.remove(2)
self.assertEqual(2, len(self.list))
if __name__ == "__main__":
suite = unittest.TestLoader().loadTestsFromTestCase(TestCircularlyLinkedList)
unittest.TextTestRunner(verbosity=2).run(suite)