-
Notifications
You must be signed in to change notification settings - Fork 0
/
linked_list.py
160 lines (117 loc) · 3.57 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
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
from __future__ import annotations
from typing import Any, Final
class Node:
def __init__(self, val: Any) -> Node:
self.value = val
self.next: Node|None = None
def __str__(self) -> str:
return f'{self.value}'
__repr__ = __str__
class SinglyLinkedList:
def __init__(self) -> SinglyLinkedList:
self.head: Node|None = None
self.length: int = 0
EMPTY_LIST_MSG: Final[str] = 'Empty List'
def __str__(self) -> str:
if not self.head:
return self.EMPTY_LIST_MSG
n = self.head
list_values: str = 'Start'
for _ in range(self.length):
list_values += f' -> {n}'
n = n.next
return list_values
__repr__ = __str__
def enqueue(self, val: Any) -> Any:
node = Node(val)
if self.head:
node.next = self.head
self.head = node
self.length += 1
return val
def dequeue(self) -> Any:
if not self.head:
raise LookupError(f'{self.EMPTY_LIST_MSG} >> No element to dequeue')
node = self.head
self.head = node.next
node.next = None
self.length -= 1
return node.value
def peek(self) -> Any:
if not self.head:
raise LookupError(f'{self.EMPTY_LIST_MSG} >> No element to peek')
return self.head.value
class DoublyLinkedList:
def __init__(self) -> DoublyLinkedList:
self.head: Node|None = None
self.tail: Node|None = None
self.length: int = 0
EMPTY_LIST_MSG: Final[str] = 'Empty List'
def __str__(self) -> str:
if not self.head:
return self.EMPTY_LIST_MSG
n = self.head
list_values: str = 'Start'
for _ in range(self.length):
list_values += f' -> {n}'
n = n.next
return list_values
__repr__ = __str__
def append(self, val: Any) -> Any:
node = Node(val)
if not self.head:
self.head = self.tail = node
else:
node.prev = self.tail
node.prev.next = node
self.tail = node
self.length += 1
return val
def prepend(self, val: Any) -> Any:
node = Node(val)
if not self.head:
self.head = self.tail = node
else:
node.next = self.head
node.next.prev = node
self.head = node
self.length += 1
return val
def pop_wrapper(func):
def pop(self) -> Any:
if not self.head:
raise LookupError(f'{self.EMPTY_LIST_MSG} >> No element to pop')
if self.length == 1:
val = self.head.value
self.head = self.tail = None
else:
val = func(self)
self.length -= 1
return val
return pop
@pop_wrapper
def pop_last(self) -> Any:
node = self.tail
self.tail = node.prev
self.tail.next = None
node.prev = None
return node.value
@pop_wrapper
def pop_first(self) -> Any:
node = self.head
self.head = node.next
self.head.prev = None
node.next = None
return node.value
def peek_wrapper(func):
def peek(self) -> Any:
if not self.head:
raise LookupError(f'{self.EMPTY_LIST_MSG} >> No element to peek')
return func(self)
return peek
@peek_wrapper
def peek_first(self) -> Any:
return self.head.value
@peek_wrapper
def peek_last(self) -> Any:
return self.tail.value