diff --git a/pydatastructs/miscellaneous_data_structures/queue.py b/pydatastructs/miscellaneous_data_structures/queue.py index 16502a571..e7e176fd0 100644 --- a/pydatastructs/miscellaneous_data_structures/queue.py +++ b/pydatastructs/miscellaneous_data_structures/queue.py @@ -1,5 +1,5 @@ -from pydatastructs.linear_data_structures import DynamicOneDimensionalArray -from pydatastructs.utils.misc_util import NoneType +from pydatastructs.linear_data_structures import DynamicOneDimensionalArray, SinglyLinkedList +from pydatastructs.utils.misc_util import NoneType, LinkedListNode from copy import deepcopy as dc __all__ = [ @@ -15,17 +15,12 @@ class Queue(object): implementation : str Implementation to be used for queue. By default, 'array' - Currently only supports 'array' - implementation. items : list/tuple Optional, by default, None The inital items in the queue. - For array implementation. dtype : A valid python type Optional, by default NoneType if item - is None, otherwise takes the data - type of DynamicOneDimensionalArray - For array implementation. + is None. Examples ======== @@ -51,6 +46,11 @@ def __new__(cls, implementation='array', **kwargs): return ArrayQueue( kwargs.get('items', None), kwargs.get('dtype', int)) + elif implementation == 'linkedlist': + return LinkedListQueue( + kwargs.get('items', None), + kwargs.get('dtype', NoneType) + ) raise NotImplementedError( "%s hasn't been implemented yet."%(implementation)) @@ -64,7 +64,9 @@ def popleft(self, *args, **kwargs): @property def is_empty(self): - return None + raise NotImplementedError( + "This is an abstract method.") + class ArrayQueue(Queue): @@ -122,3 +124,59 @@ def __str__(self): for i in range(self.front, self.rear + 1): _data.append(self.items._data[i]) return str(_data) + + +class LinkedListQueue(Queue): + + __slots__ = ['front', 'rear', 'size', '_dtype'] + + def __new__(cls, items=None, dtype=NoneType): + obj = object.__new__(cls) + obj.queue = SinglyLinkedList() + obj._dtype = dtype + if items is None: + pass + elif type(items) in (list, tuple): + if len(items) != 0 and dtype is NoneType: + obj._dtype = type(items[0]) + for x in items: + if type(x) == obj._dtype: + obj.queue.append(x) + else: + raise TypeError("Expected %s but got %s"%(obj._dtype, type(x))) + else: + raise TypeError("Expected type: list/tuple") + obj.front = obj.queue.head + obj.rear = obj.queue.tail + obj.size = obj.queue.size + return obj + + def append(self, x): + if self._dtype is NoneType: + self._dtype = type(x) + elif type(x) is not self._dtype: + raise TypeError("Expected %s but got %s"%(self._dtype, type(x))) + self.size += 1 + self.queue.append(x) + if self.front is None: + self.front = self.queue.head + self.rear = self.queue.tail + + def popleft(self): + if self.is_empty: + raise ValueError("Queue is empty.") + self.size -= 1 + return_value = self.queue.pop_left() + self.front = self.queue.head + self.rear = self.queue.tail + return return_value + + @property + def is_empty(self): + return self.size == 0 + + def __len__(self): + return self.size + + def __str__(self): + return str(self.queue) diff --git a/pydatastructs/miscellaneous_data_structures/tests/test_queue.py b/pydatastructs/miscellaneous_data_structures/tests/test_queue.py index 18f8030f0..49d52fe11 100644 --- a/pydatastructs/miscellaneous_data_structures/tests/test_queue.py +++ b/pydatastructs/miscellaneous_data_structures/tests/test_queue.py @@ -18,3 +18,21 @@ def test_Queue(): q1 = Queue() raises(ValueError, lambda: q1.popleft()) + + q1 = Queue(implementation='linkedlist') + q1.append(1) + assert raises(TypeError, lambda: q1.append('a')) + assert raises(TypeError, lambda: Queue(implementation='linkedlist', items=[0], dtype=str)) + assert raises(TypeError, lambda: Queue(implementation='linkedlist', items={0, 1})) + q1 = Queue(implementation='linkedlist', items = [0, 1]) + q1.append(2) + q1.append(3) + assert str(q1) == '[0, 1, 2, 3]' + assert len(q1) == 4 + assert q1.popleft().data == 0 + assert q1.popleft().data == 1 + assert len(q1) == 2 + assert q1.popleft().data == 2 + assert q1.popleft().data == 3 + assert len(q1) == 0 + raises(ValueError, lambda: q1.popleft())