From 8107d80dd1868e9a08af262aa536839e72369bbf Mon Sep 17 00:00:00 2001 From: shellhub Date: Sat, 24 Oct 2020 11:13:23 +0800 Subject: [PATCH 1/2] update LinkedQueue --- data_structures/queue/linked_queue.py | 160 +++++++++++++++++++------- 1 file changed, 118 insertions(+), 42 deletions(-) diff --git a/data_structures/queue/linked_queue.py b/data_structures/queue/linked_queue.py index 614c60cd1ae2..558e15598de3 100644 --- a/data_structures/queue/linked_queue.py +++ b/data_structures/queue/linked_queue.py @@ -1,74 +1,150 @@ -""" A Queue using a Linked List like structure """ -from typing import Any, Optional +""" A Queue using a linked list like structure """ class Node: - def __init__(self, data: Any, next: Optional["Node"] = None): - self.data: Any = data - self.next: Optional["Node"] = next + def __init__(self, data): + self.data = data + self.next = None + + def __str__(self): + return f"{self.data}" class LinkedQueue: """ - Linked List Queue implementing put (to end of queue), - get (from front of queue) and is_empty - >>> queue = LinkedQueue() >>> queue.is_empty() True - >>> queue.put(5) - >>> queue.put(9) - >>> queue.put('python') + >>> queue.enqueue(5) + >>> queue.enqueue(9) + >>> queue.enqueue('python') >>> queue.is_empty(); False - >>> queue.get() + >>> queue.dequeue() 5 - >>> queue.put('algorithms') - >>> queue.get() + >>> queue.enqueue('algorithms') + >>> queue.dequeue() 9 - >>> queue.get() + >>> queue.dequeue() 'python' - >>> queue.get() + >>> queue.dequeue() 'algorithms' >>> queue.is_empty() True - >>> queue.get() + >>> queue.dequeue() Traceback (most recent call last): ... - IndexError: get from empty queue + IndexError: dequeue from empty queue """ - def __init__(self) -> None: - self.front: Optional[Node] = None - self.rear: Optional[Node] = None + def __init__(self): + self.front = self.rear = None + + def __iter__(self): + node = self.front + while node: + yield node.data + node = node.next + + def __len__(self): + """ + >>> queue = LinkedQueue() + >>> for i in range(1, 6): + ... queue.enqueue(i) + >>> len(queue) + 5 + >>> for i in range(1, 6): + ... assert len(queue) == 6 - i + ... _ = queue.dequeue() + >>> len(queue) + 0 + """ + return len(tuple(iter(self))) + + def __str__(self): + """ + >>> queue = LinkedQueue() + >>> for i in range(1, 4): + ... queue.enqueue(i) + >>> queue.enqueue("Python") + >>> queue.enqueue(3.14) + >>> queue.enqueue(True) + >>> str(queue) + '1 <- 2 <- 3 <- Python <- 3.14 <- True' + """ + return " <- ".join(str(item) for item in self) def is_empty(self) -> bool: - """ returns boolean describing if queue is empty """ - return self.front is None + """ + >>> queue = LinkedQueue() + >>> queue.is_empty() + True + >>> for i in range(1, 6): + ... queue.enqueue(i) + >>> queue.is_empty() + False + """ + return len(self) == 0 - def put(self, item: Any) -> None: - """ append item to rear of queue """ - node: Node = Node(item) + def enqueue(self, item) -> None: + """ + >>> queue = LinkedQueue() + >>> queue.dequeue() + Traceback (most recent call last): + ... + IndexError: dequeue from empty queue + >>> for i in range(1, 6): + ... queue.enqueue(i) + >>> str(queue) + '1 <- 2 <- 3 <- 4 <- 5' + """ + node = Node(item) if self.is_empty(): - # the queue contains just the single element - self.front = node - self.rear = node + self.front = self.rear = node else: - # not empty, so we add it to the rear of the queue assert isinstance(self.rear, Node) self.rear.next = node self.rear = node - def get(self) -> Any: - """ returns and removes item at front of queue """ + def dequeue(self): + """ + >>> queue = LinkedQueue() + >>> queue.dequeue() + Traceback (most recent call last): + ... + IndexError: dequeue from empty queue + >>> queue = LinkedQueue() + >>> for i in range(1, 6): + ... queue.enqueue(i) + >>> for i in range(1, 6): + ... assert queue.dequeue() == i + >>> len(queue) + 0 + """ if self.is_empty(): - raise IndexError("get from empty queue") - else: - # "remove" element by having front point to the next one - assert isinstance(self.front, Node) - node: Node = self.front - self.front = node.next - if self.front is None: - self.rear = None - - return node.data + raise IndexError("dequeue from empty queue") + assert isinstance(self.front, Node) + node = self.front + self.front = self.front.next + if self.front is None: + self.rear = None + return node.data + + def clear(self) -> None: + """ + >>> queue = LinkedQueue() + >>> for i in range(1, 6): + ... queue.enqueue(i) + >>> queue.clear() + >>> len(queue) + 0 + >>> str(queue) + '' + """ + self.front = self.rear = None + + +if __name__ == "__main__": + from doctest import testmod + + testmod() \ No newline at end of file From fa0af344fbe41b379eea682626b616f6c14c02b9 Mon Sep 17 00:00:00 2001 From: shellhub Date: Sat, 24 Oct 2020 17:37:48 +0800 Subject: [PATCH 2/2] add type hint and rename --- data_structures/queue/linked_queue.py | 61 ++++++++++++++------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/data_structures/queue/linked_queue.py b/data_structures/queue/linked_queue.py index 558e15598de3..8526ad311ed0 100644 --- a/data_structures/queue/linked_queue.py +++ b/data_structures/queue/linked_queue.py @@ -1,12 +1,13 @@ """ A Queue using a linked list like structure """ +from typing import Any class Node: - def __init__(self, data): + def __init__(self, data: Any) -> None: self.data = data self.next = None - def __str__(self): + def __str__(self) -> str: return f"{self.data}" @@ -15,29 +16,29 @@ class LinkedQueue: >>> queue = LinkedQueue() >>> queue.is_empty() True - >>> queue.enqueue(5) - >>> queue.enqueue(9) - >>> queue.enqueue('python') + >>> queue.put(5) + >>> queue.put(9) + >>> queue.put('python') >>> queue.is_empty(); False - >>> queue.dequeue() + >>> queue.get() 5 - >>> queue.enqueue('algorithms') - >>> queue.dequeue() + >>> queue.put('algorithms') + >>> queue.get() 9 - >>> queue.dequeue() + >>> queue.get() 'python' - >>> queue.dequeue() + >>> queue.get() 'algorithms' >>> queue.is_empty() True - >>> queue.dequeue() + >>> queue.get() Traceback (most recent call last): ... IndexError: dequeue from empty queue """ - def __init__(self): + def __init__(self) -> None: self.front = self.rear = None def __iter__(self): @@ -46,29 +47,29 @@ def __iter__(self): yield node.data node = node.next - def __len__(self): + def __len__(self) -> int: """ >>> queue = LinkedQueue() >>> for i in range(1, 6): - ... queue.enqueue(i) + ... queue.put(i) >>> len(queue) 5 >>> for i in range(1, 6): ... assert len(queue) == 6 - i - ... _ = queue.dequeue() + ... _ = queue.get() >>> len(queue) 0 """ return len(tuple(iter(self))) - def __str__(self): + def __str__(self) -> str: """ >>> queue = LinkedQueue() >>> for i in range(1, 4): - ... queue.enqueue(i) - >>> queue.enqueue("Python") - >>> queue.enqueue(3.14) - >>> queue.enqueue(True) + ... queue.put(i) + >>> queue.put("Python") + >>> queue.put(3.14) + >>> queue.put(True) >>> str(queue) '1 <- 2 <- 3 <- Python <- 3.14 <- True' """ @@ -80,21 +81,21 @@ def is_empty(self) -> bool: >>> queue.is_empty() True >>> for i in range(1, 6): - ... queue.enqueue(i) + ... queue.put(i) >>> queue.is_empty() False """ return len(self) == 0 - def enqueue(self, item) -> None: + def put(self, item) -> None: """ >>> queue = LinkedQueue() - >>> queue.dequeue() + >>> queue.get() Traceback (most recent call last): ... IndexError: dequeue from empty queue >>> for i in range(1, 6): - ... queue.enqueue(i) + ... queue.put(i) >>> str(queue) '1 <- 2 <- 3 <- 4 <- 5' """ @@ -106,18 +107,18 @@ def enqueue(self, item) -> None: self.rear.next = node self.rear = node - def dequeue(self): + def get(self) -> Any: """ >>> queue = LinkedQueue() - >>> queue.dequeue() + >>> queue.get() Traceback (most recent call last): ... IndexError: dequeue from empty queue >>> queue = LinkedQueue() >>> for i in range(1, 6): - ... queue.enqueue(i) + ... queue.put(i) >>> for i in range(1, 6): - ... assert queue.dequeue() == i + ... assert queue.get() == i >>> len(queue) 0 """ @@ -134,7 +135,7 @@ def clear(self) -> None: """ >>> queue = LinkedQueue() >>> for i in range(1, 6): - ... queue.enqueue(i) + ... queue.put(i) >>> queue.clear() >>> len(queue) 0 @@ -147,4 +148,4 @@ def clear(self) -> None: if __name__ == "__main__": from doctest import testmod - testmod() \ No newline at end of file + testmod()