-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdoubly_linked_list.py
252 lines (205 loc) · 6.68 KB
/
doubly_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
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
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
#!/usr/bin/python3
"""
Module Name:
doubly_linked_list
Module Description:
This module contains two class to manage a double linked list
Module Classes:
- Node
- LinkedList
Module Attributes:
- None
"""
class Node:
"""
Represents a node in a linked list
"""
def __init__(self, data: int, next_node=None, prev_node=None) -> None:
"""
Initializes a new instance of the Node class.
Parameters:
data (int): the value of the node.
next_node (Node, optional): the next node in the linked list. Defaults to None.
prev_node (Node, optional): the previous node in the linked list. Defaults to None.
Returns: None.
"""
self.data = data
self.next_node = next_node
self.prev_node = prev_node
class LinkedList:
"""
Represents a doubly linked list
"""
def __init__(self, head=None, tail=None) -> None:
"""
Initializes a new instance of the LinkedList class.
Parameters:
head (Node, optional): the head node of the linked list. Defaults to None.
tail (Node, optional): the tail node of the linked list. Defaults to None.
Returns: None.
"""
self.head = head
self.tail = tail
def append_at_final(self, node_value: int) -> None:
"""
Inserts a new node at the beginning of the linked list.
Parameters:
value (int): the value of the new node to be inserted.
Returns: None.
Raises:
ValueError: if the value passed as parameter is not an integer or float.
"""
new_node = Node(node_value)
if self.head is None:
self.head = new_node
self.tail = new_node
return
new_node.next_node = self.head
self.head = new_node
new_node.next_node.prev_node = new_node
def append(self, node_value: int) -> None:
"""
Inserts a new node at the end of the linked list.
Parameters:
value (int): the value of the new node to be inserted.
Returns: None.
Raises:
ValueError: if the value passed as parameter is not an integer.
"""
new_node = Node(node_value)
if self.tail is None:
self.head = new_node
self.tail = new_node
return
self.tail.next_node = new_node
new_node.prev_node = self.tail
self.tail = new_node
def add(self, node_value):
"""
Adds a new node with the given value after the head node.
Parameters:
value (int): The value of the new node to be inserted.
Returns: None.
"""
new_node = Node(node_value)
if self.head is None:
self.head = new_node
self.tail = new_node
return
if self.head.next_node is None:
# If there is only one node in the list, add new node after the head
new_node.prev_node = self.head
self.head.next_node = new_node
self.tail = new_node
else:
# If there are more than one nodes in the list, add new node after the head
new_node.next_node = self.head.next_node
new_node.prev_node = self.head
self.head.next_node.prev_node = new_node
self.head.next_node = new_node
def swap(self) -> None:
"""
Swaps the positions of the head node and its next node.
Returns: None.
"""
if self.head.next_node is None:
# If there is only one node in the list, do nothing
return
elif self.head.next_node.next_node is None:
# If there is only two nodes in the list
node = self.head
self.head = self.head.next_node
self.head.prev_node = None
self.head.next_node = node
node.prev_node = self.head
node.next_node = None
else:
# If there are more than two nodes in the list
node = self.head
self.head = self.head.next_node
node.next_node = self.head.next_node
node.prev_node = self.head
self.head.next_node.prev_node = node
self.head.next_node = node
def pop(self) -> int:
"""
Removes and returns the value of the last node in the linked list.
Returns:
int: The value of the last node in the linked list.
Raises:
IndexError: If the linked list is empty.
"""
node_to_pop = self.tail
number_to_pop = node_to_pop.data
self.tail = node_to_pop.prev_node
if self.tail:
self.tail.next_node = None
else:
self.head = None
del node_to_pop
return number_to_pop
def popleft(self) -> int:
"""
Removes and returns the value of the first node in the linked list.
Returns:
int: The value of the first node in the linked list.
Raises:
IndexError: If the linked list is empty.
"""
node_to_pop = self.head
number_to_pop = node_to_pop.data
self.head = node_to_pop.next_node
del node_to_pop
return number_to_pop
def print(self) -> None:
"""
Prints the linked list from the beginning to the end.
Returns: None.
"""
current = self.head
while current:
print(current.data)
current = current.next_node
def print_rev(self) -> None:
"""
Prints the linked list from the end to the beginning.
Returns: None.
"""
current = self.tail
while current:
print(current.data)
current = current.prev_node
def pint(self) -> None:
"""
Prints the value of the head node.
Returns: None.
"""
print(self.head.data)
def to_dict(self) -> dict:
"""
Converts the linked list to a dictionary.
Returns:
dict: the dictionary representation of the linked list.
"""
dict_list = []
current = self.head
while current:
dict_list.append(current.data)
current = current.next_node
return {"data": dict_list}
def save(self) -> None:
"""
Saves the linked list into the storage defined by the user.
"""
from .__init__ import storage
dict_list = self.to_dict()
storage.save(dict_list)
def reload(self) -> None:
"""
Reload the information
"""
from .__init__ import storage
data = storage.reload()
if data is not None:
for value in list(data.values())[0]:
self.append(value)