diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb index c8a32a4..bf5177b 100644 --- a/lib/heap_sort.rb +++ b/lib/heap_sort.rb @@ -1,8 +1,18 @@ # This method uses a heap to sort an array. -# Time Complexity: ? -# Space Complexity: ? -def heap_sort(list) - raise NotImplementedError, "Method not implemented yet..." +# Time Complexity: O(n) +# Space Complexity: O(n) +def heapsort(list) + # raise NotImplementedError, "Method not implemented yet..." + mamasHeap = MinHeap.new() + list.each do |e| + mamasHeap.add(e) + end + # p mamasHeap + new_list = [] + while !mamasHeap.empty? + new_list << mamasHeap.remove() + end + return new_list end \ No newline at end of file diff --git a/lib/min_heap.rb b/lib/min_heap.rb index 6eaa630..018c84b 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -14,18 +14,31 @@ def initialize end # This method adds a HeapNode instance to the heap - # Time Complexity: ? - # Space Complexity: ? + # Time Complexity: O(log n) + # Space Complexity: O(n) def add(key, value = key) - raise NotImplementedError, "Method not implemented yet..." + # raise NotImplementedError, "Method not implemented yet..." + # add new node into array (@store) <- shovel or push + # run the heap_up( arr.length - 1 or @store[-1]) + @store.push(HeapNode.new(key, value)) + heap_up(@store.length - 1) end # 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(n) def remove() - raise NotImplementedError, "Method not implemented yet..." + # raise NotImplementedError, "Method not implemented yet..." + if @store.empty? + return nil + end + + swap(0, @store.length - 1) + result = @store.pop #pop removes the last item in an array + + heap_down(0) unless @store.empty? + return result.value end @@ -44,10 +57,11 @@ def to_s end # This method returns true if the heap is empty - # Time complexity: ? - # Space complexity: ? + # Time complexity: O(1) + # Space complexity: O(1) def empty? - raise NotImplementedError, "Method not implemented yet..." + # raise NotImplementedError, "Method not implemented yet..." + return true if @store.empty? end private @@ -55,17 +69,36 @@ def empty? # 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: ? - def heap_up(index) - + # Time complexity: O(logn) + # Space complexity: O(n) + def heap_up(index) #index of array, key/val, look at key + parent = (index - 1)/2 + + while index != 0 && @store[parent].key > @store[index].key + swap(parent, index) + index = parent + parent = (index - 1)/2 + end end # This helper method takes an index and - # moves it up the heap if it's smaller - # than it's parent node. + # moves it down the heap, if it's larger than its children. def heap_down(index) - raise NotImplementedError, "Method not implemented yet..." + # raise NotImplementedError, "Method not implemented yet..." + # return if @store[index].key < r_child && @store[index].key < l_child # index is already set to 0 + r_child = 2 * index + 2 + l_child = 2 * index + 1 + if !(@store[l_child] == nil && @store[r_child] == nil) + if @store[index].key > @store[l_child].key || (@store[r_child] != nil && @store[index].key > @store[r_child].key) + if @store[r_child] == nil || @store[l_child].key < @store[r_child].key + swap(index, l_child) + heap_down(l_child) + else + swap(index, r_child) + heap_down(r_child) + end + end + end end # If you want a swap method... you're welcome @@ -74,4 +107,24 @@ def swap(index_1, index_2) @store[index_1] = @store[index_2] @store[index_2] = temp end -end \ No newline at end of file +end + + + +################################################ +# IGNORE ME! (spiraled) + +# until ((@store[index].key <= @store[l_child].key) && (@store[index].key <= @store[r_child].key) -# while the parent is less than + # if (@store[l_child].key < @store[index].key) && @store[l_child].key < @store[r_child].key + # swap(index, l_child) + # index = l_child + # l_child.nil? + # elsif (@store[r_child].key < @store[index].key) && (@store[r_child].key < @store[l_child].key) + # swap(index, r_child) + # index = r_child + # r_child = 2 * index + 2 + # r_child.nil? + # else + # return + # end + # end \ No newline at end of file diff --git a/test/heapsort_test.rb b/test/heapsort_test.rb index 34402ac..7ce79b7 100644 --- a/test/heapsort_test.rb +++ b/test/heapsort_test.rb @@ -1,6 +1,6 @@ require_relative "test_helper" -xdescribe "heapsort" do +describe "heapsort" do it "sorts an empty array" do # Arrange list = [] diff --git a/test/min_heap_test.rb b/test/min_heap_test.rb index 186d4c2..785a5ef 100644 --- a/test/min_heap_test.rb +++ b/test/min_heap_test.rb @@ -52,30 +52,30 @@ end it "can remove nodes in the proper order" do - # Arrange - heap.add(3, "Pasta") - heap.add(6, "Soup") - heap.add(1, "Pizza") - heap.add(0, "Donuts") - heap.add(16, "Cookies") - heap.add(57, "Cake") + # Arrange + heap.add(3, "Pasta") + heap.add(6, "Soup") + heap.add(1, "Pizza") + heap.add(0, "Donuts") + heap.add(16, "Cookies") + heap.add(57, "Cake") - # Act - removed = heap.remove + # Act + removed = heap.remove - # Assert - expect(removed).must_equal "Donuts" + # Assert + expect(removed).must_equal "Donuts" - # Another Act - removed = heap.remove + # Another Act + removed = heap.remove - # Another assert - expect(removed).must_equal "Pizza" + # Another assert + expect(removed).must_equal "Pizza" - # Another Act - removed = heap.remove + # Another Act + removed = heap.remove - # Another assert - expect(removed).must_equal "Pasta" + # Another assert + expect(removed).must_equal "Pasta" end end \ No newline at end of file