diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index 3b834a5..556f9f3 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -1,8 +1,41 @@ +from heapq import heappush, heappop +from heaps.min_heap import MinHeap - -def heap_sort(list): +def heap_sort(list): # O(n) """ 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() + for num in list: + # has heap_up inside and sorts it in heap everytime new node is added + heap.add(num) + + # while the heap is not empty, it removes the most minimal value which is always the root + index = 0 + while not heap.empty(): + # puts sorted nums back in list using index + # remove is O(log n) + list[index] = heap.remove() + index += 1 + + return list + +# from class +# Time: n log n +# space: n +def heapsort(unsorted): + heap = [] + for item in unsorted: + heappush(heap, item) + # heapq is putting all of this together. append will treat it like any other list and does order it + + ordered = [] + while len(heap) > 0: + value = heappop(heap) + ordered.append(value) + + # returns ordered elements + return ordered + +print(heapsort([4,7,1,33,0,-8])) \ No newline at end of file diff --git a/heaps/min_heap.py b/heaps/min_heap.py index f6fe4e0..43a779b 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -19,18 +19,29 @@ 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) """ - 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 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 @@ -44,10 +55,11 @@ def __str__(self): def empty(self): """ This method returns true if the heap is empty - Time complexity: ? - Space complexity: ? + Time complexity: O(n) + Space complexity: O(1) """ - pass + if len(self.store) == 0: + return True def heap_up(self, index): @@ -57,10 +69,22 @@ 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: O(1) + + check my value vs parent's value + if parent is larger + swap with parent + recursively call heap_up from new location """ - pass + if index == 0: + return + + parent = (index - 1) // 2 + store = self.store + if store[parent].key > store[index].key: + self.swap(parent, index) + self.heap_up(parent) def heap_down(self, index): """ This helper method takes an index and @@ -68,7 +92,21 @@ def heap_down(self, index): larger than either of its children and continues until the heap property is reestablished. """ - pass + left_child = index * 2 + 1 + right_child = index * 2 + 2 + store = self.store + if left_child < len(self.store): + if right_child < len(self.store): + if store[left_child].key < store[right_child].key: + smaller = left_child + else: + smaller = right_child + else: + smaller = left_child + + if store[index].key > store[smaller].key: + self.swap(index, smaller) + self.heap_down(smaller) def swap(self, index_1, index_2):