-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlinked_list.py
81 lines (72 loc) · 2.77 KB
/
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
""" Linked-node based implementation of List ADT. """
from node import ListNode
from abstract_list import List, T
__author__ = 'Maria Garcia de la Banda and Brendon Taylor. Modified by Alexey Ignatiev'
__docformat__ = 'reStructuredText'
class LinkedList(List[T]):
""" List ADT implemented with linked nodes. """
def __init__(self, dummy_capacity=1) -> None:
""" Linked-list object initialiser. """
super(LinkedList, self).__init__()
self.head = None
def clear(self):
""" Clear the list. """
# first call clear() for the base class
super(LinkedList, self).clear()
self.head = None
def __setitem__(self, index: int, item: T) -> None:
""" Magic method. Insert the item at a given position. """
node_at_index = self.__get_node_at_index(index)
node_at_index.item = item
def __getitem__(self, index: int) -> T:
""" Magic method. Return the element at a given position. """
node_at_index = self.__get_node_at_index(index)
return node_at_index.item
def index(self, item: T) -> int:
""" Find the position of a given item in the list. """
current = self.head
index = 0
while current is not None and current.item != item:
current = current.next
index += 1
if current is None:
raise ValueError('Item is not in list')
else:
return index
def __get_node_at_index(self, index: int) -> ListNode[T]:
""" Get node object at a given position. """
if 0 <= index and index < len(self):
current = self.head
for i in range(index):
current = current.next
return current
else:
raise ValueError('Index out of bounds')
def delete_at_index(self, index: int) -> T:
""" Delete item at a given position. """
try:
previous_node = self.__get_node_at_index(index-1)
except ValueError as e:
if self.is_empty():
raise ValueError('List is empty')
elif index == 0:
item = self.head.item
self.head = self.head.next
else:
raise e
else:
item = previous_node.next.item
previous_node.next = previous_node.next.next
self.length -= 1
return item
def insert(self, index: int, item: T) -> None:
""" Insert an item at a given position. """
new_node = ListNode(item)
if index == 0:
new_node.next = self.head
self.head = new_node
else:
previous_node = self.__get_node_at_index(index - 1)
new_node.next = previous_node.next
previous_node.next = new_node
self.length += 1