@@ -23,6 +23,12 @@ class Queue(object):
23
23
dtype : A valid python type
24
24
Optional, by default NoneType if item
25
25
is None.
26
+ Required only for 'array' implementation.
27
+ double_ended : bool
28
+ Optional, by default, False.
29
+ Set to True if the queue should support
30
+ additional, appendleft and pop operations
31
+ from left and right sides respectively.
26
32
27
33
Examples
28
34
========
@@ -47,10 +53,12 @@ def __new__(cls, implementation='array', **kwargs):
47
53
if implementation == 'array' :
48
54
return ArrayQueue (
49
55
kwargs .get ('items' , None ),
50
- kwargs .get ('dtype' , int ))
56
+ kwargs .get ('dtype' , int ),
57
+ kwargs .get ('double_ended' , False ))
51
58
elif implementation == 'linked_list' :
52
59
return LinkedListQueue (
53
- kwargs .get ('items' , None )
60
+ kwargs .get ('items' , None ),
61
+ kwargs .get ('double_ended' , False )
54
62
)
55
63
else :
56
64
raise NotImplementedError (
@@ -60,10 +68,24 @@ def __new__(cls, implementation='array', **kwargs):
60
68
def methods (cls ):
61
69
return ['__new__' ]
62
70
71
+ def _double_ended_check (self ):
72
+ if not self ._double_ended :
73
+ raise NotImplementedError (
74
+ "This method is only supported for "
75
+ "double ended queues." )
76
+
63
77
def append (self , * args , ** kwargs ):
64
78
raise NotImplementedError (
65
79
"This is an abstract method." )
66
80
81
+ def appendleft (self , * args , ** kwargs ):
82
+ raise NotImplementedError (
83
+ "This is an abstract method." )
84
+
85
+ def pop (self , * args , ** kwargs ):
86
+ raise NotImplementedError (
87
+ "This is an abstract method." )
88
+
67
89
def popleft (self , * args , ** kwargs ):
68
90
raise NotImplementedError (
69
91
"This is an abstract method." )
@@ -76,52 +98,94 @@ def is_empty(self):
76
98
77
99
class ArrayQueue (Queue ):
78
100
79
- __slots__ = ['front ' ]
101
+ __slots__ = ['_front' , '_rear' , '_double_ended ' ]
80
102
81
- def __new__ (cls , items = None , dtype = NoneType ):
103
+ def __new__ (cls , items = None , dtype = NoneType , double_ended = False ):
82
104
if items is None :
83
105
items = DynamicOneDimensionalArray (dtype , 0 )
84
106
else :
85
107
dtype = type (items [0 ])
86
108
items = DynamicOneDimensionalArray (dtype , items )
87
109
obj = object .__new__ (cls )
88
- obj .items , obj .front = items , - 1
110
+ obj .items , obj ._front = items , - 1
89
111
if items .size == 0 :
90
- obj .front = - 1
112
+ obj ._front = - 1
113
+ obj ._rear = - 1
91
114
else :
92
- obj .front = 0
115
+ obj ._front = 0
116
+ obj ._rear = items ._num - 1
117
+ obj ._double_ended = double_ended
93
118
return obj
94
119
95
120
@classmethod
96
121
def methods (cls ):
97
- return ['__new__' , 'append' , 'popleft' , 'rear' ,
98
- 'is_empty' , '__len__' , '__str__' ]
122
+ return ['__new__' , 'append' , 'appendleft' , 'popleft' ,
123
+ 'pop' , 'is_empty' , '__len__' , '__str__' , 'front' ,
124
+ 'rear' ]
99
125
100
126
def append (self , x ):
101
127
if self .is_empty :
102
- self .front = 0
128
+ self ._front = 0
103
129
self .items ._dtype = type (x )
104
130
self .items .append (x )
131
+ self ._rear += 1
132
+
133
+ def appendleft (self , x ):
134
+ self ._double_ended_check ()
135
+ temp = []
136
+ if self .is_empty :
137
+ self ._front = 0
138
+ self ._rear = - 1
139
+ self .items ._dtype = type (x )
140
+ temp .append (x )
141
+ for i in range (self ._front , self ._rear + 1 ):
142
+ temp .append (self .items ._data [i ])
143
+ self .items = DynamicOneDimensionalArray (type (temp [0 ]), temp )
144
+ self ._rear += 1
105
145
106
146
def popleft (self ):
107
147
if self .is_empty :
108
148
raise IndexError ("Queue is empty." )
109
- return_value = dc (self .items [self .front ])
110
- front_temp = self .front
111
- if self .front == self .rear :
112
- self .front = - 1
149
+ return_value = dc (self .items [self ._front ])
150
+ front_temp = self ._front
151
+ if self ._front == self ._rear :
152
+ self ._front = - 1
153
+ self ._rear = - 1
113
154
else :
114
155
if (self .items ._num - 1 )/ self .items ._size < \
115
156
self .items ._load_factor :
116
- self .front = 0
157
+ self ._front = 0
117
158
else :
118
- self .front += 1
159
+ self ._front += 1
119
160
self .items .delete (front_temp )
120
161
return return_value
121
162
163
+ def pop (self ):
164
+ self ._double_ended_check ()
165
+ if self .is_empty :
166
+ raise IndexError ("Queue is empty." )
167
+
168
+ return_value = dc (self .items [self ._rear ])
169
+ rear_temp = self ._rear
170
+ if self ._front == self ._rear :
171
+ self ._front = - 1
172
+ self ._rear = - 1
173
+ else :
174
+ if (self .items ._num - 1 )/ self .items ._size < \
175
+ self .items ._load_factor :
176
+ self ._front = 0
177
+ else :
178
+ self ._rear -= 1
179
+ self .items .delete (rear_temp )
180
+ return return_value
181
+
182
+ @property
183
+ def front (self ):
184
+ return self ._front
185
+
122
186
@property
123
187
def rear (self ):
124
- return self .items . _last_pos_filled
188
+ return self ._rear
125
189
126
190
@property
127
191
def is_empty (self ):
@@ -132,16 +196,15 @@ def __len__(self):
132
196
133
197
def __str__ (self ):
134
198
_data = []
135
- for i in range (self .front , self .rear + 1 ):
199
+ for i in range (self ._front , self ._rear + 1 ):
136
200
_data .append (self .items ._data [i ])
137
201
return str (_data )
138
202
139
-
140
203
class LinkedListQueue (Queue ):
141
204
142
- __slots__ = ['queue' ]
205
+ __slots__ = ['queue' , '_double_ended' ]
143
206
144
- def __new__ (cls , items = None ):
207
+ def __new__ (cls , items = None , double_ended = False ):
145
208
obj = object .__new__ (cls )
146
209
obj .queue = SinglyLinkedList ()
147
210
if items is None :
@@ -151,16 +214,29 @@ def __new__(cls, items=None):
151
214
obj .append (x )
152
215
else :
153
216
raise TypeError ("Expected type: list/tuple" )
217
+ obj ._double_ended = double_ended
154
218
return obj
155
219
156
220
@classmethod
157
221
def methods (cls ):
158
- return ['__new__' , 'append' , 'popleft ' , 'rear ' ,
159
- 'is_empty' , '__len__' , '__str__' , 'front' , 'size ' ]
222
+ return ['__new__' , 'append' , 'appendleft ' , 'pop' , 'popleft ' ,
223
+ 'is_empty' , '__len__' , '__str__' , 'front' , 'rear ' ]
160
224
161
225
def append (self , x ):
162
226
self .queue .append (x )
163
227
228
+ def appendleft (self , x ):
229
+ self ._double_ended_check ()
230
+ if self ._double_ended :
231
+ self .queue .appendleft (x )
232
+
233
+ def pop (self ):
234
+ self ._double_ended_check ()
235
+ if self .is_empty :
236
+ raise IndexError ("Queue is empty." )
237
+ return_value = self .queue .popright ()
238
+ return return_value
239
+
164
240
def popleft (self ):
165
241
if self .is_empty :
166
242
raise IndexError ("Queue is empty." )
@@ -169,7 +245,7 @@ def popleft(self):
169
245
170
246
@property
171
247
def is_empty (self ):
172
- return self .size == 0
248
+ return self .__len__ () == 0
173
249
174
250
@property
175
251
def front (self ):
@@ -179,12 +255,8 @@ def front(self):
179
255
def rear (self ):
180
256
return self .queue .tail
181
257
182
- @property
183
- def size (self ):
184
- return self .queue .size
185
-
186
258
def __len__ (self ):
187
- return self .size
259
+ return self .queue . size
188
260
189
261
def __str__ (self ):
190
262
return str (self .queue )
0 commit comments