From bc7f58ccd7bc5607873cfab35ad9d178b87d3946 Mon Sep 17 00:00:00 2001 From: Alli-Oops Date: Wed, 5 Jan 2022 16:28:53 -0800 Subject: [PATCH 1/2] saving progress, incomplete assignment --- heaps/heap_sort.py | 2 +- heaps/min_heap.py | 91 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 78 insertions(+), 15 deletions(-) diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index 3b834a5..1452165 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -2,7 +2,7 @@ def heap_sort(list): """ This method uses a heap to sort an array. - Time Complexity: ? + Time Complexity: O(log n) Space Complexity: ? """ pass \ No newline at end of file diff --git a/heaps/min_heap.py b/heaps/min_heap.py index a1340e3..649cf88 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -1,23 +1,43 @@ 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) +# We begin our implementation of a binary heap with the constructor. +# Since the entire binary heap can be represented by a single list, +# we could make it so that +# all the constructor will do is initialize the list and an attribute currentSize to track the current size of the heap. +# class BinHeap: +# def initialize(self): +# self.heapList = [0] # the zero is there so that simple integer division +# self.currentSize = 0 class MinHeap: - def __init__(self): - self.store = [] + self.store = [] # this is the list where we store stuff + + def parent(): + + def find_left_child(): + def find_right_child(): + + 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(logn) + Space Complexity: O(n) """ - pass + self.store.append(HeapNode.new(key,value)) + # we will append a new value to the end of the + # Compare the new node with it's parent + # If they are out of order swap and heap-up + # using the parent's index number. + self.heap_up(len(self.store) - 1) def remove(self): """ This method removes and returns an element from the heap @@ -25,8 +45,12 @@ def remove(self): Time Complexity: ? Space Complexity: ? """ - pass + if self.store.empty? + return nil + + self.swap(0, self.store.last - 1) + result = self.store.pop() def __str__(self): @@ -47,21 +71,60 @@ def empty(self): 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. + 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: ? """ - pass + while self.store[parent].key > self.store[index].key: + if index == 0: + break + self.swap(index, parent) + index = parent + parent = self.find_parent(index) def heap_down(self, index): """ This helper method takes an index and - moves it up the heap if it's smaller + moves the corresponding element down the heap if it's + larger than either of its children and continues until + the heap property is reestablished. than it's parent node. """ - pass + smallest_child = self.find_smallest_child(index) + if smallest_child and index < len(self.store): + if self.store[index].key > self.store[smallest_child].key: + + # start heap_down with the root (index 0) + lc = self.find_left_child(index) + rc = self.find_right_child(index) + while not self.store[index].key <= self.store[lc].key or not self.store[index].key <= self.store[rc].key: + if self.store[index].key > self.store[lc].key and self.store[lc].key + smallest_child = lc + else: + smallest_child = rc + self.swap(smallest_child, index) + index = smallest_child + lc = self.find_left_child(index) + rc = self.find_right_child(index) + if lc > len(self.store)-1 or rc > len(self.store)-1: + break + return + + #self.heap_down(0) unless self.store.empty? + #return result + + while (i * 2) <= self.currentSize: + mc = self.minChild(i) + if self.heapList[i] > self.heapList[mc]: + tmp = self.heapList[i] + self.heapList[i] = self.heapList[mc] + self.heapList[mc] = tmp + i = mc + - def swap(self, index_1, index_2): """ Swaps two elements in self.store at index_1 and index_2 From 88af095a036bdf30e732f792c6d2019a2630e894 Mon Sep 17 00:00:00 2001 From: Alli-Oops Date: Wed, 5 Jan 2022 19:40:53 -0800 Subject: [PATCH 2/2] passing tests --- heaps/heap_sort.py | 12 +++- heaps/min_heap.py | 156 +++++++++++++++++++-------------------------- 2 files changed, 75 insertions(+), 93 deletions(-) diff --git a/heaps/heap_sort.py b/heaps/heap_sort.py index 1452165..6b3b5b6 100644 --- a/heaps/heap_sort.py +++ b/heaps/heap_sort.py @@ -1,8 +1,16 @@ - +from heaps.min_heap import MinHeap def heap_sort(list): """ This method uses a heap to sort an array. Time Complexity: O(log n) Space Complexity: ? """ - pass \ No newline at end of file + heap = MinHeap() + for num in list: + heap.add(num) + + heap_list = [] + while heap.store: + num = heap.remove() + heap_list.append(num) + return heap_list \ No newline at end of file diff --git a/heaps/min_heap.py b/heaps/min_heap.py index 649cf88..26deb57 100644 --- a/heaps/min_heap.py +++ b/heaps/min_heap.py @@ -5,56 +5,46 @@ def __init__(self, key, value): def __str__(self): return str(self.value) - -# We begin our implementation of a binary heap with the constructor. -# Since the entire binary heap can be represented by a single list, -# we could make it so that -# all the constructor will do is initialize the list and an attribute currentSize to track the current size of the heap. -# class BinHeap: -# def initialize(self): -# self.heapList = [0] # the zero is there so that simple integer division -# self.currentSize = 0 + class MinHeap: def __init__(self): self.store = [] # this is the list where we store stuff - def parent(): - - def find_left_child(): - - def find_right_child(): - - - 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: O(logn) - Space Complexity: O(n) + """ + This method adds a HeapNode instance to the heap + If value == None the new node's value should be set to key + Time Complexity: O(logn) + Space Complexity: O(n) """ - self.store.append(HeapNode.new(key,value)) - # we will append a new value to the end of the - # Compare the new node with it's parent - # If they are out of order swap and heap-up - # using the parent's index number. + if not value: + value = key + self.store.append(HeapNode(key, value)) + # we will append a new value to the end of the heap + # Compare the new node with it's parent + # If they are out of order swap and heap-up + # using the parent's index number. 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: ? + """ + This method removes and returns an element from the heap + maintaining the heap structure + Time Complexity: ? + Space Complexity: ? """ + if self.empty(): + return None - if self.store.empty? - return nil - - self.swap(0, self.store.last - 1) - result = self.store.pop() + self.swap(0, len(self.store) - 1) + remove_val = self.store.pop() + self.heap_down(0) + return remove_val.value def __str__(self): - """ This method lets you print the heap, when you're testing your app. + """ + This method lets you print the heap, when you're testing your app. """ if len(self.store) == 0: return "[]" @@ -62,74 +52,58 @@ def __str__(self): def empty(self): - """ This method returns true if the heap is empty - Time complexity: ? - Space complexity: ? + """ + This method returns true if the heap is empty + Time complexity: O(1) + Space complexity: O(1) """ - pass + return len(self.store) == 0 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 - property is reestablished. - - This could be **very** helpful for the add method. - Time complexity: ? - Space complexity: ? """ - while self.store[parent].key > self.store[index].key: - if index == 0: - break - self.swap(index, parent) - index = parent - parent = self.find_parent(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 + property is reestablished. + This could be **very** helpful for the add method. + Time complexity: O() + Space complexity: 0() + """ + parent_index = (index-1)//2 + while index>0 and self.store[index].key < self.store[parent_index].key: + self.swap(index,parent_index) + index = parent_index + parent_index = (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 - larger than either of its children and continues until - the heap property is reestablished. - than it's parent node. + """ + 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. + than it's parent node. """ - smallest_child = self.find_smallest_child(index) - if smallest_child and index < len(self.store): - if self.store[index].key > self.store[smallest_child].key: - - # start heap_down with the root (index 0) - lc = self.find_left_child(index) - rc = self.find_right_child(index) - while not self.store[index].key <= self.store[lc].key or not self.store[index].key <= self.store[rc].key: - if self.store[index].key > self.store[lc].key and self.store[lc].key - smallest_child = lc - else: - smallest_child = rc - self.swap(smallest_child, index) - index = smallest_child - lc = self.find_left_child(index) - rc = self.find_right_child(index) - if lc > len(self.store)-1 or rc > len(self.store)-1: - break - return - #self.heap_down(0) unless self.store.empty? - #return result + childOne = index*2+1 + childTwo = childOne+1 - while (i * 2) <= self.currentSize: - mc = self.minChild(i) - if self.heapList[i] > self.heapList[mc]: - tmp = self.heapList[i] - self.heapList[i] = self.heapList[mc] - self.heapList[mc] = tmp - i = mc + if len(self.store)>childTwo and self.store[childOne].key>self.store[childTwo].key: + childOne=childTwo + if len(self.store)<=childOne: + return None + + if self.store[childOne].key