From b0730ff4fadcbe6a4d0a763a883c47d782009b11 Mon Sep 17 00:00:00 2001 From: Gabe Kelemen Date: Thu, 5 May 2022 15:48:07 -0400 Subject: [PATCH 1/5] Add MinHeap add, remove, empty methods --- heaps/min_heap.py | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/heaps/min_heap.py b/heaps/min_heap.py index f6fe4e0..b4eb742 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -22,7 +22,16 @@ def add(self, key, value = None): Time Complexity: ? Space Complexity: ? """ - pass + # check for value, if no value, set value of new node to key + if value == None: + value = key + + # if value, create new node and add to self.store, end of heap + node = HeapNode(key, value) + self.store.append(node) + # use heap_up helper to check the value of appended node against parent and order heap accordingly + self.heap_up(len(self.store) -1) + def remove(self): """ This method removes and returns an element from the heap @@ -30,7 +39,22 @@ def remove(self): Time Complexity: ? Space Complexity: ? """ - pass + # check if empty + if self.empty(): + return None + + # if not empty, swap the last index with the root + self.swap(0, len(self.store)-1) + + # remove the root and store it + min = self.store.pop() + + # call heap_down helper? + self.heap_down(0) + + #return the value of the root - the min value + return min.value + @@ -47,7 +71,7 @@ def empty(self): Time complexity: ? Space complexity: ? """ - pass + return len(self.store) == 0 def heap_up(self, index): @@ -60,7 +84,18 @@ def heap_up(self, index): Time complexity: ? Space complexity: ? """ - pass + # compare the index to the parent index and if larger, swap node positions + + if index == 0: + return None + + # use swap helper to swap the node with the parent node + + parent = (index -1) // 2 + if self.store[index].key < self.store[parent].key: + self.swap(index, parent) + #continue to heap_up until the root is reached and every node ordered correctly + self.heap_up(parent) def heap_down(self, index): """ This helper method takes an index and From dbfa92201ac779e7d69c279e75653c7651abd5fb Mon Sep 17 00:00:00 2001 From: Gabe Kelemen Date: Thu, 5 May 2022 16:30:01 -0400 Subject: [PATCH 2/5] Start heap sort --- heaps/heap_sort.py | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index 3b834a5..b20189c 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -1,8 +1,24 @@ - - def heap_sort(list): """ This method uses a heap to sort an array. - Time Complexity: ? - Space Complexity: ? + Time Complexity: O(n log n) + Space Complexity: O(n) """ - pass \ No newline at end of file + + heap = MinHeap() + + if not list: + return[] + + # add all elements in list to heap + for num in list: + heap.add(num) + + index = 0 + # while heap not empty, remove each node to create ordered list + while not heap.empty(): + list[index] = heap.remove() + index += 1 + + return list + + \ No newline at end of file From cd3a53010bce035ab0c28d6354204e3eec6454f3 Mon Sep 17 00:00:00 2001 From: Gabe Kelemen Date: Thu, 12 May 2022 16:24:40 -0400 Subject: [PATCH 3/5] Adds heap_down method --- heaps/min_heap.py | 54 +++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/heaps/min_heap.py b/heaps/min_heap.py index b4eb742..9663d0b 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -19,8 +19,8 @@ def __init__(self): 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: ? + Time Complexity: O(log n) + Space Complexity: O(1) """ # check for value, if no value, set value of new node to key if value == None: @@ -29,34 +29,32 @@ def add(self, key, value = None): # if value, create new node and add to self.store, end of heap node = HeapNode(key, value) self.store.append(node) - # use heap_up helper to check the value of appended node against parent and order heap accordingly - self.heap_up(len(self.store) -1) + # use heap_up helper to check the value of appended node against parent to order heap + self.heap_up(len(self.store) - 1) def remove(self): """ This method removes and returns an element from the heap maintaining the heap structure - Time Complexity: ? - Space Complexity: ? + Time Complexity: O(log n) + Space Complexity: O(1) """ # check if empty if self.empty(): return None # if not empty, swap the last index with the root - self.swap(0, len(self.store)-1) + self.swap(0, len(self.store) - 1) # remove the root and store it min = self.store.pop() - # call heap_down helper? + # call heap_down helper self.heap_down(0) #return the value of the root - the min value - return min.value + return str(min.value) - - def __str__(self): """ This method lets you print the heap, when you're testing your app. @@ -68,8 +66,8 @@ 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) """ return len(self.store) == 0 @@ -81,17 +79,18 @@ def heap_up(self, index): property is reestablished. This could be **very** helpful for the add method. - Time complexity: ? - Space complexity: ? + Time complexity: O(log n) + Space complexity: makes a recursive call """ # compare the index to the parent index and if larger, swap node positions + if index == 0: return None # use swap helper to swap the node with the parent node - parent = (index -1) // 2 + parent = (index - 1) // 2 if self.store[index].key < self.store[parent].key: self.swap(index, parent) #continue to heap_up until the root is reached and every node ordered correctly @@ -103,9 +102,28 @@ def heap_down(self, index): larger than either of its children and continues until the heap property is reestablished. """ - pass + + left = index * 2 + 1 + right = index * 2 + 2 + + # check if out of range and determine if which node is smaller + if left < len(self.store): + + # set min_child to left node if right child is larger or if there is no right child + if right < len(self.store): + if self.store[left].key < self.store[right].key: + smaller = left + else: + smaller = right + else: + smaller = left + + # swap the node with the smaller child node + if self.store[index].key > self.store[smaller].key: + self.swap(index, smaller) + self.heap_down(smaller) + - def swap(self, index_1, index_2): """ Swaps two elements in self.store at index_1 and index_2 From 701c089aa37a9e0603f1fc000d95a623cb774a0f Mon Sep 17 00:00:00 2001 From: Gabe Kelemen Date: Thu, 12 May 2022 16:53:27 -0400 Subject: [PATCH 4/5] Remove (str) from return in remove method --- heaps/heap_sort.py | 4 +++- heaps/min_heap.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index b20189c..2e4fe14 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -1,3 +1,5 @@ +from heaps.min_heap import MinHeap + def heap_sort(list): """ This method uses a heap to sort an array. Time Complexity: O(n log n) @@ -7,7 +9,7 @@ def heap_sort(list): heap = MinHeap() if not list: - return[] + return [] # add all elements in list to heap for num in list: diff --git a/heaps/min_heap.py b/heaps/min_heap.py index 9663d0b..99a8af3 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -53,7 +53,7 @@ def remove(self): self.heap_down(0) #return the value of the root - the min value - return str(min.value) + return min.value def __str__(self): From 02591fd588ec33fa0bff9c0701abd81f02e55eff Mon Sep 17 00:00:00 2001 From: Gabe Kelemen Date: Thu, 12 May 2022 17:00:05 -0400 Subject: [PATCH 5/5] Change heap_down variable name for readability --- heaps/min_heap.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/heaps/min_heap.py b/heaps/min_heap.py index 99a8af3..f17f5ed 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -83,13 +83,10 @@ def heap_up(self, index): Space complexity: makes a recursive call """ # compare the index to the parent index and if larger, swap node positions - - if index == 0: return None # use swap helper to swap the node with the parent node - parent = (index - 1) // 2 if self.store[index].key < self.store[parent].key: self.swap(index, parent) @@ -103,25 +100,25 @@ def heap_down(self, index): the heap property is reestablished. """ - left = index * 2 + 1 - right = index * 2 + 2 + left_child = index * 2 + 1 + right_child = index * 2 + 2 # check if out of range and determine if which node is smaller - if left < len(self.store): + if left_child < len(self.store): - # set min_child to left node if right child is larger or if there is no right child - if right < len(self.store): - if self.store[left].key < self.store[right].key: - smaller = left + # set smaller_child to left node if right child is larger or if there is no right child + if right_child < len(self.store): + if self.store[left_child].key < self.store[right_child].key: + smaller_child = left_child else: - smaller = right + smaller_child = right_child else: - smaller = left + smaller_child = left_child # swap the node with the smaller child node - if self.store[index].key > self.store[smaller].key: - self.swap(index, smaller) - self.heap_down(smaller) + if self.store[index].key > self.store[smaller_child].key: + self.swap(index, smaller_child) + self.heap_down(smaller_child) def swap(self, index_1, index_2):