1
+ """
2
+ Implementation of double ended queue.
3
+ """
4
+ from dataclasses import dataclass
5
+ from typing import Any
6
+
7
+ class Deque :
8
+ """
9
+ Deque data structure.
10
+
11
+ Operations
12
+ ----------
13
+ append(val: Any) -> None
14
+ appendleft(val: Any) -> None
15
+ pop() -> Any
16
+ popleft() -> Any
17
+
18
+
19
+ Observers
20
+ ---------
21
+ is_empty() -> bool
22
+
23
+
24
+ Attributes
25
+ ----------
26
+ _front: _Node
27
+ front of the deque a.k.a. the first element
28
+
29
+ _back: _Node
30
+ back of the element a.k.a. the last element
31
+
32
+ _len: int
33
+ the number of nodes
34
+ """
35
+ __slots__ = ["_front" , "_back" , "_len" ]
36
+
37
+ @dataclass
38
+ class _Node :
39
+ """
40
+ Representation of a node.
41
+ Contains a value and a pointer to the next node as well as to the previous one.
42
+ """
43
+ val : Any = None
44
+ next : "_Node" = None
45
+ prev : "_Node" = None
46
+
47
+ class _Iterator :
48
+ """
49
+ Helper class for iteration. Will be used to implement iteration.
50
+
51
+ Attributes
52
+ ----------
53
+ _cur: _Node
54
+ the current node of the iteration.
55
+ """
56
+ __slots__ = ["_cur" ]
57
+
58
+ def __init__ (self , cur ):
59
+ self ._cur = cur
60
+
61
+ def __iter__ (self ):
62
+ return self
63
+
64
+ def __next__ (self ):
65
+ if self ._cur is None :
66
+ # finished iterating
67
+ raise StopIteration
68
+ val = self ._cur .val
69
+ self ._cur = self ._cur .next
70
+
71
+ return val
72
+
73
+ def __init__ (self , iterable = None ):
74
+ self ._front = self ._back = None
75
+ self ._len = 0
76
+
77
+ if iterable is not None :
78
+ # append every value to the deque
79
+ for val in iterable :
80
+ self .append (val )
81
+
82
+ def append (self , val : Any ) -> None :
83
+ """
84
+ Adds val to the end of the deque.
85
+ Time complexity: O(1)
86
+
87
+ >>> d = Deque([1, 2, 3])
88
+ >>> d.append(4)
89
+ >>> print(d)
90
+ [1, 2, 3, 4]
91
+ >>> d2 = Deque([51, "str", True])
92
+ >>> d2.append([1, "2"])
93
+ >>> print(d2)
94
+ [51, 'str', True, [1, '2']]
95
+ """
96
+ node = self ._Node (val , None , None )
97
+ if self .is_empty ():
98
+ # front = back
99
+ self ._front = self ._back = node
100
+ self ._len = 1
101
+ else :
102
+ # connect nodes
103
+ self ._back .next = node
104
+ node .prev = self ._back
105
+ self ._back = node # assign new back to the new node
106
+
107
+ self ._len += 1
108
+
109
+ # make sure there was no errors
110
+ assert not self .is_empty (), "Error on appending value."
111
+
112
+ def appendleft (self , val : Any ) -> None :
113
+ """
114
+ Adds val to the beginning of the deque.
115
+ Time complexity: O(1)
116
+
117
+ >>> d = Deque([2, 3])
118
+ >>> d.appendleft(1)
119
+ >>> print(d)
120
+ [1, 2, 3]
121
+ >>> d2 = Deque(["b", "c"])
122
+ >>> d2.appendleft("a")
123
+ >>> print(d2)
124
+ ['a', 'b', 'c']
125
+ """
126
+ node = self ._Node (val , None , None )
127
+ if self .is_empty ():
128
+ # front = back
129
+ self ._front = self ._back = node
130
+ self ._len = 1
131
+ else :
132
+ # connect nodes
133
+ node .next = self ._front
134
+ self ._front .prev = node
135
+ self ._front = node # assign new front to the new node
136
+
137
+ self ._len += 1
138
+
139
+ # make sure there was no errors
140
+ assert not self .is_empty (), "Error on appending value."
141
+
142
+ def pop (self ) -> Any :
143
+ """
144
+ Removes the last element of the deque and returns it.
145
+ Time complexity: O(1)
146
+
147
+ @returns topop.val: the value of the node to pop.
148
+
149
+ >>> d = Deque([1, 2, 3, 15182])
150
+ >>> popped = d.pop()
151
+ >>> print(popped)
152
+ 15182
153
+ >>> print(d)
154
+ [1, 2, 3]
155
+ """
156
+ # make sure the deque has elements to pop
157
+ assert not self .is_empty (), "Deque is empty."
158
+
159
+ topop = self ._back
160
+ self ._back = self ._back .prev # set new back
161
+ self ._back .next = None # drop the last node - python will deallocate memory automatically
162
+
163
+ self ._len -= 1
164
+
165
+ return topop .val
166
+
167
+ def popleft (self ) -> Any :
168
+ """
169
+ Removes the first element of the deque and returns it.
170
+ Time complexity: O(1)
171
+
172
+ @returns topop.val: the value of the node to pop.
173
+
174
+ >>> d = Deque([15182, 1, 2, 3])
175
+ >>> popped = d.popleft()
176
+ >>> print(popped)
177
+ 15182
178
+ >>> print(d)
179
+ [1, 2, 3]
180
+ """
181
+ # make sure the deque has elements to pop
182
+ assert not self .is_empty (), "Deque is empty."
183
+
184
+ topop = self ._front
185
+ self ._front = self ._front .next # set new front and drop the first node
186
+ self ._front .prev = None
187
+
188
+ self ._len -= 1
189
+
190
+ return topop .val
191
+
192
+ def is_empty (self ) -> bool :
193
+ """
194
+ Checks if the deque is empty.
195
+ Time complexity: O(1)
196
+
197
+ >>> d = Deque([1, 2, 3])
198
+ >>> print(d.is_empty())
199
+ False
200
+ >>> d2 = Deque()
201
+ >>> print(d2.is_empty())
202
+ True
203
+ """
204
+ return self ._front is None
205
+
206
+ def __len__ (self ) -> int :
207
+ """
208
+ Implements len() function. Returns the length of the deque.
209
+ Time complexity: O(1)
210
+
211
+ >>> d = Deque([1, 2, 3])
212
+ >>> print(len(d))
213
+ 3
214
+ >>> d2 = Deque()
215
+ >>> print(len(d2))
216
+ 0
217
+ """
218
+ return self ._len
219
+
220
+ def __eq__ (self , other ) -> bool :
221
+ """
222
+ Implements "==" operator. Returns if *self* is equal to *other*.
223
+ Time complexity: O(n)
224
+
225
+ >>> d = Deque([1, 2, 3])
226
+ >>> d2 = Deque([1, 2, 3])
227
+ >>> print(d == d2)
228
+ True
229
+ >>> d3 = Deque([1, 2])
230
+ >>> print(d == d3)
231
+ False
232
+ """
233
+ me = self ._front
234
+ oth = other ._front
235
+
236
+ # if the length of the deques are not the same, they are not equal
237
+ if len (self ) != len (other ):
238
+ return False
239
+
240
+ while me is not None and oth is not None :
241
+ # compare every value
242
+ if me .val != oth .val :
243
+ return False
244
+ me = me .next
245
+ oth = oth .next
246
+
247
+ return True
248
+
249
+ def __iter__ (self ):
250
+ """
251
+ Implements iteration.
252
+ Time complexity: O(1)
253
+
254
+ >>> d = Deque([1, 2, 3])
255
+ >>> for v in d:
256
+ ... print(v)
257
+ 1
258
+ 2
259
+ 3
260
+ """
261
+ return Deque ._Iterator (self ._front )
262
+
263
+ def __repr__ (self ) -> str :
264
+ """
265
+ Implements representation of the deque.
266
+ Time complexity: O(n)
267
+
268
+ >>> d = Deque([1, 2, 3])
269
+ >>> print(d)
270
+ [1, 2, 3]
271
+ """
272
+ l = []
273
+ aux = self ._front
274
+ while aux is not None :
275
+ # append the values in a list to display
276
+ l .append (aux .val )
277
+ aux = aux .next
278
+
279
+ return '[' + ', ' .join (repr (x ) for x in l ) + ']'
0 commit comments