From 9903c241729a384aababd032ae02e5adfb171130 Mon Sep 17 00:00:00 2001 From: Christian Spencer <64983017+Crintion@users.noreply.github.com> Date: Wed, 26 Jan 2022 12:13:42 -0800 Subject: [PATCH] All tests passing --- heaps/heap_sort.py | 20 +++++++-- heaps/min_heap.py | 101 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 93 insertions(+), 28 deletions(-) diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index 3b834a5..23e5da2 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -1,8 +1,20 @@ - +from .min_heap import MinHeap def heap_sort(list): """ This method uses a heap to sort an array. - Time Complexity: ? - Space Complexity: ? + Time Complexity: O(nlogn) (Each add is log(n), n nodes must be added) + Space Complexity: O(n) """ - pass \ No newline at end of file + + heap = MinHeap() + + for item in list: + heap.add(item) + + # Iterate through list by index and remove heap items to build sorted list in the original array + for i in range(0, len(list)): + list[i] = heap.remove() + + return list + + \ No newline at end of file diff --git a/heaps/min_heap.py b/heaps/min_heap.py index 0095872..8492843 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -1,5 +1,8 @@ +import math + + class HeapNode: - + def __init__(self, key, value): self.key = key self.value = value @@ -11,73 +14,123 @@ def __repr__(self): return str(self.value) - class MinHeap: def __init__(self): self.store = [] - - def add(self, key, value = None): + 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)) : add tail is constant rebalancing is log(n) + Space Complexity: O(N+1) """ + if value is not None: + self.store.append((key, value)) + else: + self.store.append((key, key)) + # Bubble up to re balance tree + + self.heap_up(len(self.store)-1) # list -1 index is last in list (python) + + print(self.store) pass 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)) : remove head and replace with tail is constant. re balancing is log(n) + Space Complexity: O(1) : """ - pass + if self.empty(): + return + min = self.store[0] # set aside root value + self.store[0] = self.store[-1] # Delete root value and replace with last node + self.store.pop(-1) + self.heap_down(0) # re balance the tree from the root position + return min[1] # return value removed from heap - def __str__(self): """ This method lets you print the heap, when you're testing your app. """ if len(self.store) == 0: return "[]" - return f"[{', '.join([str(element) for element in self.store])}]" + return f"[{', '.join([str(element[1]) for element in self.store])}]" def empty(self): """ This method returns true if the heap is empty - Time complexity: ? - Space complexity: ? + Time complexity: O(nlogn) + Space complexity: O(n) """ - pass + if len(self.store) == 0: + return True + + return False # ?? implicit? + # "Bubble up" to root def heap_up(self, index): """ This helper method takes an index and - moves the corresponding element up the heap, if + moves the corresponding element 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: ? + Time complexity: O(logn) + Space complexity: O(n +1) """ - pass + if index == 0: + return + + if index == 1 or index == 2: + parent_index = 0 + else: + parent_index = int(math.ceil((index-2)/2)) + # if parent_index <= 1: + # parent_index = int(1) + + print("Parent") + print(parent_index) + print(type(parent_index)) + print("index") + print(index) + + + if self.store[int(parent_index)][0] > self.store[index][0]: + self.swap(index, parent_index) + self.heap_up(parent_index) + + return + # "filter down" to child position. def heap_down(self, index): - """ This helper method takes an index and - moves the corresponding element down the heap if it's + """ This helper method takes an index and + moves the corresponding element 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 + + if left_index >= len(self.store) or right_index >= len(self.store): + return + + if self.store[left_index][0] < self.store[index][0]: + self.swap(left_index, index) + self.heap_down(index) + + elif self.store[right_index][0] < self.store[index][0]: + self.swap(right_index, index) + self.heap_down(index) - def swap(self, index_1, index_2): """ Swaps two elements in self.store at index_1 and index_2 used for heap_up & heap_down """ + print("Swapping ", index_1, " ", index_2) temp = self.store[index_1] self.store[index_1] = self.store[index_2] - self.store[index_2] = temp + self.store[index_2] = temp \ No newline at end of file