diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index 3b834a5..e7f377f 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -1,8 +1,17 @@ - +from heaps.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) + Space Complexity O(n): """ - pass \ No newline at end of file + list1 = MinHeap() + list2 = [] + for j in list: + list1.add(j) + for _ in range(len(list1.store)): + element = list1.remove() + list2.append(element) + return list2 + + diff --git a/heaps/min_heap.py b/heaps/min_heap.py index a1340e3..efbc1a7 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -1,32 +1,48 @@ class HeapNode: - def initialize(self, key, value): + def __init__(self, key, value): self.key = key self.value = value + + def __str__(self): + return str(self.value) class MinHeap: def __init__(self): self.store = [] + + def __len__(self): + return len(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: ? + Time Complexity: O(log n) + Space Complexity: O(1) """ - pass + if value == None: + value = key + newNode = HeapNode(key, value) + self.store.append(newNode) + last = len(self.store) - 1 + self.heap_up(last) + 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 def __str__(self): @@ -34,33 +50,63 @@ def __str__(self): """ if len(self.store) == 0: return "[]" - return f"[{', '.join([str(element) for element in self.store])}]" + return f"[{', '.join([str(element.value) for element in self.store])}]" 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 + if len(self.store) == 0: + return True + return False def heap_up(self, index): """ This helper method takes an index and moves it up the heap, if it is less than it's parent node. It could be **very** helpful for the add method. - Time complexity: ? - Space complexity: ? + Time complexity: O(log n) + Space complexity: O(1) """ - pass + if index == 0: + return + + parentIndex = (index -1)//2 + if self.store[index].key < self.store[parentIndex].key: + self.swap(index, parentIndex) + self.heap_up(parentIndex) + + def heap_down(self, index): """ This helper method takes an index and moves it up the heap if it's smaller than it's parent node. """ - pass - + size = len(self.store) + while True: + l, r = index * 2 + 1, index * 2 + 2 + if max(l, r) < size: + if self.store[index].key < self.store[l].key and self.store[index].key < self.store[r].key: break + elif self.store[l].key > self.store[r].key: + self.swap(index, r) + index = r + else: + self.swap(index, l) + index = l + elif l < size: + if self.store[l].key < self.store[index].key: + self.swap(index, l) + index = l + else: break + elif r < size: + if self.store[r].key < self.store[index].key: + self.swap(index, r) + index = r + else: break + else: break def swap(self, index_1, index_2): """ Swaps two elements in self.store @@ -70,3 +116,6 @@ def swap(self, index_1, index_2): temp = self.store[index_1] self.store[index_1] = self.store[index_2] self.store[index_2] = temp + + + diff --git a/tests/test_min_heap.py b/tests/test_min_heap.py index 74867dc..4280d77 100644 --- a/tests/test_min_heap.py +++ b/tests/test_min_heap.py @@ -57,7 +57,6 @@ def test_it_can_remove_nodes_in_proper_order(heap): heap.add(0, "Donuts") heap.add(16, "Cookies") - # Act returned_items = ["Donuts", "Pizza", "Pasta", "Soup", "Cookies", "Cake"]