Skip to content

Commit 5f69948

Browse files
authored
Added naive implementation of priority queue (#196)
1 parent 150c6c2 commit 5f69948

File tree

3 files changed

+115
-2
lines changed

3 files changed

+115
-2
lines changed

pydatastructs/miscellaneous_data_structures/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from .queue import (
2121
Queue,
22+
PriorityQueue
2223
)
2324
__all__.extend(queue.__all__)
2425

pydatastructs/miscellaneous_data_structures/queue.py

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from copy import deepcopy as dc
44

55
__all__ = [
6-
'Queue'
6+
'Queue',
7+
'PriorityQueue'
78
]
89

910
class Queue(object):
@@ -171,3 +172,97 @@ def __len__(self):
171172

172173
def __str__(self):
173174
return str(self.queue)
175+
176+
class PriorityQueue(object):
177+
"""
178+
Represents the concept of priority queue.
179+
180+
Parameters
181+
==========
182+
183+
implementation: str
184+
The implementation which is to be
185+
used for supporting operations
186+
of priority queue.
187+
The following implementations are supported,
188+
'linked_list' -> Linked list implementation.
189+
Optional, by default, 'linked_list' implementation
190+
is used.
191+
comp: function
192+
The comparator to be used while comparing priorities.
193+
Must return a bool object.
194+
By default, `lambda u, v: u > v` is used to compare
195+
priorities i.e., maximum priority elements are extracted
196+
by pop operation.
197+
198+
Examples
199+
========
200+
201+
>>> from pydatastructs import PriorityQueue
202+
>>> pq = PriorityQueue()
203+
>>> pq.push(1, 2)
204+
>>> pq.push(2, 3)
205+
>>> pq.pop()
206+
2
207+
>>> pq2 = PriorityQueue(comp=lambda u, v: u < v)
208+
>>> pq2.push(1, 2)
209+
>>> pq2.push(2, 3)
210+
>>> pq2.pop()
211+
1
212+
213+
References
214+
==========
215+
216+
.. [1] https://en.wikipedia.org/wiki/Priority_queue#Naive_implementations
217+
"""
218+
219+
def __new__(cls, implementation='linked_list', **kwargs):
220+
if implementation == 'linked_list':
221+
return LinkedListPriorityQueue(
222+
kwargs.get("comp", lambda u, v: u > v)
223+
)
224+
225+
def push(self, value, priority):
226+
raise NotImplementedError(
227+
"This is an abstract method.")
228+
229+
def pop(self):
230+
raise NotImplementedError(
231+
"This is an abstract method.")
232+
233+
@property
234+
def is_empty(self):
235+
raise NotImplementedError(
236+
"This is an abstract method.")
237+
238+
class LinkedListPriorityQueue(PriorityQueue):
239+
240+
__slots__ = ['items', 'comp']
241+
242+
def __new__(cls, comp=lambda u, v: u > v):
243+
obj = object.__new__(cls)
244+
obj.items = SinglyLinkedList()
245+
obj.comp = comp
246+
return obj
247+
248+
def push(self, value, priority):
249+
self.items.append(value, priority)
250+
251+
def pop(self):
252+
if self.is_empty:
253+
raise IndexError("Priority queue is empty.")
254+
255+
walk = self.items.head
256+
i, max_i, max_p = 0, 0, walk.data
257+
while walk is not None:
258+
if self.comp(walk.data, max_p):
259+
max_i = i
260+
max_p = walk.data
261+
i += 1
262+
walk = walk.next
263+
pop_val = self.items.extract(max_i)
264+
return pop_val.key
265+
266+
@property
267+
def is_empty(self):
268+
return self.items.size == 0

pydatastructs/miscellaneous_data_structures/tests/test_queue.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from pydatastructs.miscellaneous_data_structures import Queue
2-
from pydatastructs.miscellaneous_data_structures.queue import ArrayQueue, LinkedListQueue
2+
from pydatastructs.miscellaneous_data_structures.queue import (
3+
ArrayQueue, LinkedListQueue, PriorityQueue,
4+
LinkedListPriorityQueue)
35
from pydatastructs.utils.raises_util import raises
46
from pydatastructs.utils.misc_util import _check_type
57

@@ -57,3 +59,18 @@ def test_LinkedListQueue():
5759
q1.popleft()
5860

5961
assert rear.key == q1.popleft().key
62+
63+
def test_PriorityQueue():
64+
pq1 = PriorityQueue(implementation='linked_list')
65+
assert _check_type(pq1, LinkedListPriorityQueue) is True
66+
assert raises(NotImplementedError, lambda: Queue(implementation=''))
67+
68+
def test_LinkedListPriorityQueue():
69+
pq1 = PriorityQueue(implementation='linked_list')
70+
pq1.push(1, 2)
71+
pq1.push(2, 3)
72+
pq1.push(3, 4)
73+
assert pq1.pop() == 3
74+
assert pq1.pop() == 2
75+
assert pq1.pop() == 1
76+
assert raises(IndexError, lambda: pq1.pop())

0 commit comments

Comments
 (0)