-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathLinked List.py
More file actions
188 lines (165 loc) · 5.82 KB
/
Linked List.py
File metadata and controls
188 lines (165 loc) · 5.82 KB
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
class Node:
"""Class to represent a node in Python3"""
def __init__(self, data):
self.data = data # Node value
self.next = None # Next node
class LinkedList:
"""Class to represent a linked list in Python3"""
def __init__(self):
self._first = None # First element of list
self._size = 0 # The size of list
def getItemByIndex(self, index):
"""Auxiliary method that returns the node by the index"""
pointer = self._first
for _ in range(index):
if pointer:
pointer = pointer.next
else:
raise IndexError("Index out of range")
return pointer
def processIndex(self, index):
"""Auxiliary method that helps with negative indexs"""
if index is None:
index = self._size - 1
elif index == self._size or abs(index) > self._size:
raise IndexError("Index out of range")
if index < 0:
index = self._size + index
return index
def append(self, elem):
"""Appends a new element in the end of list"""
if self._first: # if is not None
pointer = self._first
while pointer.next:
pointer = pointer.next
pointer.next = Node(elem)
else:
self._first = Node(elem)
self._size += 1
def remove(self, elem):
"""Removes the first occurrence of the element from the list"""
if self._size == 0:
raise Exception("Empty list")
index = self.index(elem)
if index == 0:
self._first = self._first.next
self._size -= 1
else:
pointer = self.getItemByIndex(index - 1)
pointer.next = pointer.next.next
self._size -= 1
def empty(self):
"""Returns true if the stack is empty, otherwise, it returns false"""
if self._size == 0:
return True
return False
def insert(self, index, elem):
"""Inserts a new element by index"""
if index < 0 and abs(index) > self._size:
index = 0
elif index < 0:
index = self._size + index
if index == 0:
pointer = self.getItemByIndex(index)
aux = Node(elem)
aux.next, self._first = pointer, aux
self._size += 1
elif index < self._size:
pointer = self.getItemByIndex(index - 1)
aux = Node(elem)
aux.next, pointer.next = pointer.next, aux
self._size += 1
else:
self.append(elem)
def pop(self, index=None):
"""Removes and returns the last element from the list"""
if self._size == 0:
raise Exception("Empty list")
index = self.processIndex(index)
if index == 0:
elem = self._first.data
self._first = self._first.next
self._size -= 1
return elem
pointer = self.getItemByIndex(index - 1)
elem = pointer.next.data
pointer.next = pointer.next.next
self._size -= 1
return elem
def clear(self):
"""Restores the list to its starting point (Empty)"""
self._first = None
self._size = 0
def count(self, elem):
"""Returns the number of elements with the specified value"""
pointer = self._first
cont = 0
while pointer != None:
if pointer.data == elem:
cont += 1
pointer = pointer.next
return cont
def index(self, elem):
"""Returns the index of specified element"""
pointer = self._first
cont = 0
while pointer:
if pointer.data == elem:
return cont
else:
pointer = pointer.next
cont += 1
raise ValueError(f"{elem} not in list")
def reverse(self):
"""Reverses the original list"""
if self._size == 0:
raise IndexError("Empty list")
for i in range(self._size - 1, -1, -1):
self.append(self.pop(i))
def createReverse(self):
"""Creates and returns a reversed new list"""
if self._size == 0:
raise IndexError("Empty list")
new = LinkedList()
for i in range(self._size - 1, -1, -1):
new.append(self[i])
return new
def __len__(self):
"""Returns the size of list; Ex: len(obj)"""
return self._size
def __getitem__(self, index):
"""Returns an element that corresponding to the index; Ex: obj[index]"""
index = self.processIndex(index)
pointer = self.getItemByIndex(index)
return pointer.data
def __setitem__(self, index, elem):
"""Sets the value by the index; Ex: obj[index] = value"""
index = self.processIndex(index)
pointer = self.getItemByIndex(index)
pointer.data = elem
def __delitem__(self, index):
"""Removes an element that corresponding to the index; Ex: obj[index]"""
index = self.processIndex(index)
if index == 0:
pointer = self.getItemByIndex(index)
self._first = pointer.next
else:
pointer = self.getItemByIndex(index - 1)
pointer.next = pointer.next.next
self._size -= 1
def __del__(self):
"""Destructor method"""
def __str__(self):
"""Method to represent a linked list (user)"""
rep = "\033[1;31m" + "head" + "\033[0;0m" + " -> "
pointer = self._first
while pointer != None:
rep += f"{pointer.data} -> "
if pointer.next is None:
break
pointer = pointer.next
rep += "\033[1;34m" + "None" + "\033[0;0m"
return rep
def __repr__(self):
"""Method to represent a linked list (developer)"""
return str(self)