From c4cb3e4c1d91b0a809a7c7cb723387cda3dd4c58 Mon Sep 17 00:00:00 2001 From: Mac Date: Sun, 15 May 2022 11:33:04 -0700 Subject: [PATCH 1/3] chore: fix heap_up bug --- heaps/min_heap.py | 92 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 69 insertions(+), 23 deletions(-) diff --git a/heaps/min_heap.py b/heaps/min_heap.py index f6fe4e0..880e45a 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -1,3 +1,5 @@ + + class HeapNode: def __init__(self, key, value): @@ -15,25 +17,36 @@ class MinHeap: def __init__(self): self.store = [] - def add(self, key, value = None): - """ This method adds a HeapNode instance to the heap - If value == None the new node's value should be set to key - Time Complexity: ? - Space Complexity: ? + """ Adds a HeapNode instance to the heap + If value == None the new node's value is set to key + Time Complexity: O(log n) + Space Complexity: O(1) """ - pass + if value == None: + value = key + + node = HeapNode(key, value) + + self.store.append(node) + + self.heap_up(len(self.store) - 1) def remove(self): - """ This method removes and returns an element from the heap + """ Removes and returns root element from the heap maintaining the heap structure - Time Complexity: ? - Space Complexity: ? + Time Complexity: O(log n) + Space Complexity: O(1) """ - pass + if self.empty: + return None + + self.swap(0, len(self.store) - 1) + min = self.store.pop() + self.heap_down(0) + return min.value - def __str__(self): """ This method lets you print the heap, when you're testing your app. """ @@ -44,33 +57,66 @@ def __str__(self): def empty(self): """ This method returns true if the heap is empty - Time complexity: ? - Space complexity: ? + Time complexity: O(1) + Space complexity: O(1) """ - pass + return self.store == None def heap_up(self, index): - """ This helper method takes an index and - moves the corresponding element up the heap, if - it is less than it's parent node until the Heap + """ Moves the element identified by index up the heap + If it is less than it's parent node until the Heap property is reestablished. - This could be **very** helpful for the add method. Time complexity: ? Space complexity: ? """ - pass + if index == 0: + return + + parent = self.store[(index - 1)//2] + + if self.store[index].key < parent.key: + self.swap(index, (index - 1)//2) + self.heap_up((index - 1)//2) def heap_down(self, index): - """ This helper method takes an index and - moves the corresponding element down the heap if it's + """ moves element at corresponding index down the heap if it's larger than either of its children and continues until the heap property is reestablished. """ - pass + left_index = (index * 2) + 1 + right_index = (index * 2) + 2 + parent = self.store[index] + left_child = self.store[left_index] + right_child = self.store[right_index] - + if left_child == None: + return + + if left_child and right_child: + if parent.key > left_child.key and parent.key > right_child.key: + if left_child.key > right_child.key: + self.swap(index, right_index) + self.heap_down(right_index) + else: + self.swap(index, left_index) + self.heap_down(left_index) + if parent.key > left_child.key: + self.swap(index, left_index) + self.heap_down(left_index) + if parent.key > right_child.key: + self.swap(index, right_index) + self.heap_down(right_index) + else: + return + + if parent.key > left_child.key: + self.swap(index, left_index) + self.heap_down(left_index) + + return + def swap(self, index_1, index_2): """ Swaps two elements in self.store at index_1 and index_2 From 61f2b1b3848248ef3617b4bcfa1e60fe19630bf3 Mon Sep 17 00:00:00 2001 From: Mac Date: Sun, 15 May 2022 13:02:14 -0700 Subject: [PATCH 2/3] chore: fix heap_down bug --- heaps/min_heap.py | 49 +++++++++++++++++------------------------------ 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/heaps/min_heap.py b/heaps/min_heap.py index 880e45a..fde5ec3 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -21,7 +21,7 @@ def add(self, key, value = None): """ Adds a HeapNode instance to the heap If value == None the new node's value is set to key Time Complexity: O(log n) - Space Complexity: O(1) + Space Complexity: O(n) """ if value == None: value = key @@ -38,12 +38,14 @@ def remove(self): Time Complexity: O(log n) Space Complexity: O(1) """ - if self.empty: + if self.empty(): return None self.swap(0, len(self.store) - 1) min = self.store.pop() - self.heap_down(0) + + if not self.empty(): + self.heap_down(0) return min.value @@ -60,7 +62,7 @@ def empty(self): Time complexity: O(1) Space complexity: O(1) """ - return self.store == None + return len(self.store) == 0 def heap_up(self, index): @@ -68,8 +70,8 @@ def heap_up(self, index): If it is less than it's parent node until the Heap property is reestablished. - Time complexity: ? - Space complexity: ? + Time complexity: O(1) + Space complexity: O(n) """ if index == 0: return @@ -88,35 +90,20 @@ def heap_down(self, index): left_index = (index * 2) + 1 right_index = (index * 2) + 2 parent = self.store[index] - left_child = self.store[left_index] - right_child = self.store[right_index] - if left_child == None: - return - - if left_child and right_child: - if parent.key > left_child.key and parent.key > right_child.key: - if left_child.key > right_child.key: - self.swap(index, right_index) - self.heap_down(right_index) - else: - self.swap(index, left_index) - self.heap_down(left_index) - if parent.key > left_child.key: - self.swap(index, left_index) - self.heap_down(left_index) - if parent.key > right_child.key: - self.swap(index, right_index) - self.heap_down(right_index) + if left_index < len(self.store): + if right_index < len(self.store): + if self.store[left_index].key < self.store[right_index].key: + smaller_child = left_index + else: + smaller_child = right_index else: - return + smaller_child = left_index - if parent.key > left_child.key: - self.swap(index, left_index) - self.heap_down(left_index) + if parent.key > self.store[smaller_child].key: + self.swap(index, smaller_child) + self.heap_down(smaller_child) - return - def swap(self, index_1, index_2): """ Swaps two elements in self.store at index_1 and index_2 From a7bd87cf4c409a0b7195eaddf1d8f01d748bad1b Mon Sep 17 00:00:00 2001 From: Mac Date: Sun, 15 May 2022 13:10:46 -0700 Subject: [PATCH 3/3] feat: add heap_sort functionality --- heaps/heap_sort.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index 3b834a5..9c38b31 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -1,8 +1,19 @@ - +from heapq import heappush, heappop def heap_sort(list): """ This method uses a heap to sort an array. Time Complexity: ? Space Complexity: ? """ - pass \ No newline at end of file + heap = [] + + for item in list: + heappush(heap, item) + + ordered = [] + + while len(heap) > 0: + value = heappop(heap) + ordered.append(value) + + return ordered \ No newline at end of file