@@ -23,6 +23,12 @@ class Queue(object):
2323 dtype : A valid python type
2424 Optional, by default NoneType if item
2525 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.
2632
2733 Examples
2834 ========
@@ -47,10 +53,12 @@ def __new__(cls, implementation='array', **kwargs):
4753 if implementation == 'array' :
4854 return ArrayQueue (
4955 kwargs .get ('items' , None ),
50- kwargs .get ('dtype' , int ))
56+ kwargs .get ('dtype' , int ),
57+ kwargs .get ('double_ended' , False ))
5158 elif implementation == 'linked_list' :
5259 return LinkedListQueue (
53- kwargs .get ('items' , None )
60+ kwargs .get ('items' , None ),
61+ kwargs .get ('double_ended' , False )
5462 )
5563 else :
5664 raise NotImplementedError (
@@ -60,10 +68,24 @@ def __new__(cls, implementation='array', **kwargs):
6068 def methods (cls ):
6169 return ['__new__' ]
6270
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+
6377 def append (self , * args , ** kwargs ):
6478 raise NotImplementedError (
6579 "This is an abstract method." )
6680
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+
6789 def popleft (self , * args , ** kwargs ):
6890 raise NotImplementedError (
6991 "This is an abstract method." )
@@ -76,52 +98,94 @@ def is_empty(self):
7698
7799class ArrayQueue (Queue ):
78100
79- __slots__ = ['front ' ]
101+ __slots__ = ['_front' , '_rear' , '_double_ended ' ]
80102
81- def __new__ (cls , items = None , dtype = NoneType ):
103+ def __new__ (cls , items = None , dtype = NoneType , double_ended = False ):
82104 if items is None :
83105 items = DynamicOneDimensionalArray (dtype , 0 )
84106 else :
85107 dtype = type (items [0 ])
86108 items = DynamicOneDimensionalArray (dtype , items )
87109 obj = object .__new__ (cls )
88- obj .items , obj .front = items , - 1
110+ obj .items , obj ._front = items , - 1
89111 if items .size == 0 :
90- obj .front = - 1
112+ obj ._front = - 1
113+ obj ._rear = - 1
91114 else :
92- obj .front = 0
115+ obj ._front = 0
116+ obj ._rear = items ._num - 1
117+ obj ._double_ended = double_ended
93118 return obj
94119
95120 @classmethod
96121 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' ]
99125
100126 def append (self , x ):
101127 if self .is_empty :
102- self .front = 0
128+ self ._front = 0
103129 self .items ._dtype = type (x )
104130 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
105145
106146 def popleft (self ):
107147 if self .is_empty :
108148 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
113154 else :
114155 if (self .items ._num - 1 )/ self .items ._size < \
115156 self .items ._load_factor :
116- self .front = 0
157+ self ._front = 0
117158 else :
118- self .front += 1
159+ self ._front += 1
119160 self .items .delete (front_temp )
120161 return return_value
121162
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+
122186 @property
123187 def rear (self ):
124- return self .items . _last_pos_filled
188+ return self ._rear
125189
126190 @property
127191 def is_empty (self ):
@@ -132,16 +196,15 @@ def __len__(self):
132196
133197 def __str__ (self ):
134198 _data = []
135- for i in range (self .front , self .rear + 1 ):
199+ for i in range (self ._front , self ._rear + 1 ):
136200 _data .append (self .items ._data [i ])
137201 return str (_data )
138202
139-
140203class LinkedListQueue (Queue ):
141204
142- __slots__ = ['queue' ]
205+ __slots__ = ['queue' , '_double_ended' ]
143206
144- def __new__ (cls , items = None ):
207+ def __new__ (cls , items = None , double_ended = False ):
145208 obj = object .__new__ (cls )
146209 obj .queue = SinglyLinkedList ()
147210 if items is None :
@@ -151,16 +214,29 @@ def __new__(cls, items=None):
151214 obj .append (x )
152215 else :
153216 raise TypeError ("Expected type: list/tuple" )
217+ obj ._double_ended = double_ended
154218 return obj
155219
156220 @classmethod
157221 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 ' ]
160224
161225 def append (self , x ):
162226 self .queue .append (x )
163227
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+
164240 def popleft (self ):
165241 if self .is_empty :
166242 raise IndexError ("Queue is empty." )
@@ -169,7 +245,7 @@ def popleft(self):
169245
170246 @property
171247 def is_empty (self ):
172- return self .size == 0
248+ return self .__len__ () == 0
173249
174250 @property
175251 def front (self ):
@@ -179,12 +255,8 @@ def front(self):
179255 def rear (self ):
180256 return self .queue .tail
181257
182- @property
183- def size (self ):
184- return self .queue .size
185-
186258 def __len__ (self ):
187- return self .size
259+ return self .queue . size
188260
189261 def __str__ (self ):
190262 return str (self .queue )
0 commit comments