From 541f8192c92e3f935c725660f70e0e4699748c20 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Thu, 19 Mar 2020 20:41:46 +0530 Subject: [PATCH 1/5] minor rename --- .../tests/{test_algorithm.py => test_algorithms.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename pydatastructs/linear_data_structures/tests/{test_algorithm.py => test_algorithms.py} (100%) diff --git a/pydatastructs/linear_data_structures/tests/test_algorithm.py b/pydatastructs/linear_data_structures/tests/test_algorithms.py similarity index 100% rename from pydatastructs/linear_data_structures/tests/test_algorithm.py rename to pydatastructs/linear_data_structures/tests/test_algorithms.py From f0bdbf115e5c36fc529b8b0e6803a521377e6ceb Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Sat, 21 Mar 2020 21:38:18 +0530 Subject: [PATCH 2/5] code for linked list priority queue added --- .../miscellaneous_data_structures/queue.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index d995d5107..59a0ac7d6 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -171,3 +171,46 @@ def __len__(self): def __str__(self): return str(self.queue) + +class PriorityQueue(object): + + def __new__(cls, implementation='linked_list', **kwargs): + if implementation == 'linked_list': + return LinkedListPriorityQueue() + + def push(self, value, priority): + raise NotImplementedError( + "This is an abstract method.") + + def pop(self): + raise NotImplementedError( + "This is an abstract method.") + + @property + def is_empty(self): + raise NotImplementedError( + "This is an abstract method.") + +class LinkedListPriorityQueue(PriorityQueue): + + __slots__ = ['items'] + + def __new__(cls, items=None): + obj = object.__new__(cls) + obj.items = SinglyLinkedList() + return obj + + def push(self, value, priority): + self.items.append((value, priority)) + + def pop(self): + walk = self.items.head + i, max_i, max_p = 0, None, walk.data[1] + while walk is not None: + if walk.data[1] > max_p: + max_i = i + max_p = walk.data[1] + i += 1 + walk = walk.next + pop_val = self.items.extract(max_i) + return pop_val.data[0] From e7e0b231d04af5d0c792d9507c09fef78d1ab212 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Sun, 22 Mar 2020 20:05:24 +0530 Subject: [PATCH 3/5] added code --- .../miscellaneous_data_structures/__init__.py | 1 + .../miscellaneous_data_structures/queue.py | 15 ++++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pydatastructs/miscellaneous_data_structures/__init__.py b/pydatastructs/miscellaneous_data_structures/__init__.py index f4749c685..be0827fe7 100644 --- a/pydatastructs/miscellaneous_data_structures/__init__.py +++ b/pydatastructs/miscellaneous_data_structures/__init__.py @@ -19,6 +19,7 @@ from .queue import ( Queue, + PriorityQueue ) __all__.extend(queue.__all__) diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index 59a0ac7d6..751fbf5d8 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -3,7 +3,8 @@ from copy import deepcopy as dc __all__ = [ - 'Queue' + 'Queue', + 'PriorityQueue' ] class Queue(object): @@ -195,22 +196,22 @@ class LinkedListPriorityQueue(PriorityQueue): __slots__ = ['items'] - def __new__(cls, items=None): + def __new__(cls): obj = object.__new__(cls) obj.items = SinglyLinkedList() return obj def push(self, value, priority): - self.items.append((value, priority)) + self.items.append(value, priority) def pop(self): walk = self.items.head - i, max_i, max_p = 0, None, walk.data[1] + i, max_i, max_p = 0, None, walk.data while walk is not None: - if walk.data[1] > max_p: + if walk.data > max_p: max_i = i - max_p = walk.data[1] + max_p = walk.data i += 1 walk = walk.next pop_val = self.items.extract(max_i) - return pop_val.data[0] + return pop_val.key From f10305fdc8f7ca0577d20bc03957177f0dc644ad Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Sun, 22 Mar 2020 20:57:10 +0530 Subject: [PATCH 4/5] testing done --- .../miscellaneous_data_structures/queue.py | 16 ++++++++++++---- .../tests/test_queue.py | 19 ++++++++++++++++++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index 751fbf5d8..fedc8deaf 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -194,24 +194,32 @@ def is_empty(self): class LinkedListPriorityQueue(PriorityQueue): - __slots__ = ['items'] + __slots__ = ['items', 'comp'] - def __new__(cls): + def __new__(cls, comp=lambda u, v: u > v): obj = object.__new__(cls) obj.items = SinglyLinkedList() + obj.comp = comp return obj def push(self, value, priority): self.items.append(value, priority) def pop(self): + if self.is_empty: + raise IndexError("Priority queue is empty.") + walk = self.items.head - i, max_i, max_p = 0, None, walk.data + i, max_i, max_p = 0, 0, walk.data while walk is not None: - if walk.data > max_p: + if self.comp(walk.data, max_p): max_i = i max_p = walk.data i += 1 walk = walk.next pop_val = self.items.extract(max_i) return pop_val.key + + @property + def is_empty(self): + return self.items.size == 0 diff --git a/pydatastructs/miscellaneous_data_structures/tests/test_queue.py b/pydatastructs/miscellaneous_data_structures/tests/test_queue.py index 415f0e87c..9f62e92eb 100644 --- a/pydatastructs/miscellaneous_data_structures/tests/test_queue.py +++ b/pydatastructs/miscellaneous_data_structures/tests/test_queue.py @@ -1,5 +1,7 @@ from pydatastructs.miscellaneous_data_structures import Queue -from pydatastructs.miscellaneous_data_structures.queue import ArrayQueue, LinkedListQueue +from pydatastructs.miscellaneous_data_structures.queue import ( + ArrayQueue, LinkedListQueue, PriorityQueue, + LinkedListPriorityQueue) from pydatastructs.utils.raises_util import raises from pydatastructs.utils.misc_util import _check_type @@ -57,3 +59,18 @@ def test_LinkedListQueue(): q1.popleft() assert rear.key == q1.popleft().key + +def test_PriorityQueue(): + pq1 = PriorityQueue(implementation='linked_list') + assert _check_type(pq1, LinkedListPriorityQueue) is True + assert raises(NotImplementedError, lambda: Queue(implementation='')) + +def test_LinkedListPriorityQueue(): + pq1 = PriorityQueue(implementation='linked_list') + pq1.push(1, 2) + pq1.push(2, 3) + pq1.push(3, 4) + assert pq1.pop() == 3 + assert pq1.pop() == 2 + assert pq1.pop() == 1 + assert raises(IndexError, lambda: pq1.pop()) From f4f13f925627454a0c520d4baa14dbb905036341 Mon Sep 17 00:00:00 2001 From: czgdp1807 Date: Sun, 22 Mar 2020 21:06:05 +0530 Subject: [PATCH 5/5] added docs --- .../miscellaneous_data_structures/queue.py | 45 ++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index fedc8deaf..2577786d0 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -174,10 +174,53 @@ def __str__(self): return str(self.queue) class PriorityQueue(object): + """ + Represents the concept of priority queue. + + Parameters + ========== + + implementation: str + The implementation which is to be + used for supporting operations + of priority queue. + The following implementations are supported, + 'linked_list' -> Linked list implementation. + Optional, by default, 'linked_list' implementation + is used. + comp: function + The comparator to be used while comparing priorities. + Must return a bool object. + By default, `lambda u, v: u > v` is used to compare + priorities i.e., maximum priority elements are extracted + by pop operation. + + Examples + ======== + + >>> from pydatastructs import PriorityQueue + >>> pq = PriorityQueue() + >>> pq.push(1, 2) + >>> pq.push(2, 3) + >>> pq.pop() + 2 + >>> pq2 = PriorityQueue(comp=lambda u, v: u < v) + >>> pq2.push(1, 2) + >>> pq2.push(2, 3) + >>> pq2.pop() + 1 + + References + ========== + + .. [1] https://en.wikipedia.org/wiki/Priority_queue#Naive_implementations + """ def __new__(cls, implementation='linked_list', **kwargs): if implementation == 'linked_list': - return LinkedListPriorityQueue() + return LinkedListPriorityQueue( + kwargs.get("comp", lambda u, v: u > v) + ) def push(self, value, priority): raise NotImplementedError(