From 34fd1be03fec16301fbbdd27747ee042a8fac73b Mon Sep 17 00:00:00 2001 From: sjscotton Date: Sun, 29 Sep 2019 12:50:19 -0700 Subject: [PATCH 1/3] finished heap add and remove --- lib/min_heap.rb | 42 +++++++++++++++++++++++++++++++---------- test/min_heap_test.rb | 44 +++++++++++++++++++++---------------------- 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/lib/min_heap.rb b/lib/min_heap.rb index 6eaa630..21ca505 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -8,7 +8,6 @@ def initialize(key, value) end class MinHeap - def initialize @store = [] end @@ -16,8 +15,12 @@ def initialize # This method adds a HeapNode instance to the heap # Time Complexity: ? # Space Complexity: ? + def add(key, value = key) - raise NotImplementedError, "Method not implemented yet..." + @store.append(HeapNode.new(key, value)) + curr = @store.length - 1 + + curr = heap_up(curr) end # This method removes and returns an element from the heap @@ -25,10 +28,15 @@ def add(key, value = key) # Time Complexity: ? # Space Complexity: ? def remove() - raise NotImplementedError, "Method not implemented yet..." + return if @store.empty? + last = @store.length - 1 + curr = 0 + swap(last, curr) + removed = @store.pop + heap_down(curr) + return removed.value end - # Used for Testing def to_s return "[]" if @store.empty? @@ -39,7 +47,7 @@ def to_s end output += @store.last.value + "]" - + return output end @@ -47,7 +55,7 @@ def to_s # Time complexity: ? # Space complexity: ? def empty? - raise NotImplementedError, "Method not implemented yet..." + return @store.empty? end private @@ -58,14 +66,28 @@ def empty? # Time complexity: ? # Space complexity: ? def heap_up(index) - + until index == 0 || @store[index].key >= @store[((index - 1) / 2)].key + parent = (index - 1) / 2 + swap(parent, index) if @store[parent].key > @store[index].key + index = parent + end end - # This helper method takes an index and + # This helper method takes an index and # moves it up the heap if it's smaller # than it's parent node. def heap_down(index) - raise NotImplementedError, "Method not implemented yet..." + until (index * 2 + 1) > @store.length - 1 + left = index * 2 + 1 + right = index * 2 + 2 + if right > @store.length - 1 + child = left + else + child = @store[left].key < @store[right].key ? left : right + end + @store[index].key > @store[child].key ? swap(index, child) : return + end + return end # If you want a swap method... you're welcome @@ -74,4 +96,4 @@ 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 diff --git a/test/min_heap_test.rb b/test/min_heap_test.rb index 186d4c2..6b1a05b 100644 --- a/test/min_heap_test.rb +++ b/test/min_heap_test.rb @@ -1,9 +1,9 @@ require_relative "test_helper" describe "Heap" do - let(:heap) {MinHeap.new} + let(:heap) { MinHeap.new } it "can be created" do - + # Assert expect(heap).must_be_instance_of MinHeap end @@ -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 +end From c27e04360d9c941b8ec1d40b02c7272b0494d2b1 Mon Sep 17 00:00:00 2001 From: sjscotton Date: Sun, 29 Sep 2019 13:12:52 -0700 Subject: [PATCH 2/3] Added heap_sort method --- lib/heap_sort.rb | 20 +++++++++++++++++--- test/heapsort_test.rb | 20 ++++++++++---------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb index c8a32a4..f07def0 100644 --- a/lib/heap_sort.rb +++ b/lib/heap_sort.rb @@ -2,7 +2,21 @@ # This method uses a heap to sort an array. # Time Complexity: ? -# Space Complexity: ? +# Space Complexity: def heap_sort(list) - raise NotImplementedError, "Method not implemented yet..." -end \ No newline at end of file + heap = heapify(list) + until heap.empty? + item = heap.remove() + list.append(item) + end + return list +end + +def heapify(list) + heap = MinHeap.new() + until list.empty? + item = list.pop() + heap.add(item) + end + return heap +end diff --git a/test/heapsort_test.rb b/test/heapsort_test.rb index 34402ac..cd81dfd 100644 --- a/test/heapsort_test.rb +++ b/test/heapsort_test.rb @@ -1,36 +1,36 @@ require_relative "test_helper" -xdescribe "heapsort" do +describe "heapsort" do it "sorts an empty array" do - # Arrange + # Arrange list = [] # Act - result = heapsort(list) + result = heap_sort(list) # Assert expect(result).must_equal [] end it "can sort a 1-element array" do - # Arrange + # Arrange list = [5] # Act - result = heapsort(list) + result = heap_sort(list) # Assert expect(result).must_equal [5] end - + it "can sort a 5-element array" do - # Arrange + # Arrange list = [5, 27, 3, 16, -50] # Act - result = heapsort(list) + result = heap_sort(list) # Assert expect(result).must_equal [-50, 3, 5, 16, 27] - end -end \ No newline at end of file + end +end From 79a60cf28ff55f8cf2744056066831b896c16e57 Mon Sep 17 00:00:00 2001 From: sjscotton Date: Sun, 29 Sep 2019 13:27:59 -0700 Subject: [PATCH 3/3] added time and space complexities --- lib/heap_sort.rb | 4 ++-- lib/min_heap.rb | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb index f07def0..ab0ec10 100644 --- a/lib/heap_sort.rb +++ b/lib/heap_sort.rb @@ -1,8 +1,8 @@ # This method uses a heap to sort an array. -# Time Complexity: ? -# Space Complexity: +# Time Complexity: 0(n log n) where n is the length of the list. heapify iterates through the list and for each calls add() which is 0(log n) so thats n log n for heapify, heap sort is the same, n log n. So total its 0(2 * nlogn) which reduces to n log n +# Space Complexity: 0(1), we create a new heap, but each time we add one, we remove one from the list. and then westart moving items one at a time back to the list. the length of the heap and the length of the list combined are always equal to the original list size, so we dont actually use any extra space. def heap_sort(list) heap = heapify(list) until heap.empty? diff --git a/lib/min_heap.rb b/lib/min_heap.rb index 21ca505..a48ebb1 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -13,8 +13,8 @@ def initialize end # This method adds a HeapNode instance to the heap - # Time Complexity: ? - # Space Complexity: ? + # Time Complexity: 0(log n) where n is the length of @store, everything is constant besides heap_up() which is 0(log n) + # Space Complexity: 0(1) constant sized variables def add(key, value = key) @store.append(HeapNode.new(key, value)) @@ -25,8 +25,8 @@ def add(key, value = key) # This method removes and returns an element from the heap # maintaining the heap structure - # Time Complexity: ? - # Space Complexity: ? + # Time Complexity: 0(log n) where n is the length of @store, everything is constant besides heap_down() which is 0(log n) + # Space Complexity: 0(1) constant sized variables def remove() return if @store.empty? last = @store.length - 1 @@ -52,8 +52,8 @@ def to_s end # This method returns true if the heap is empty - # Time complexity: ? - # Space complexity: ? + # Time complexity: O(1) Length and empty are constant time in ruby, not enumerables. + # Space complexity: O(1) no variables created at all def empty? return @store.empty? end @@ -63,8 +63,8 @@ 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: ? + # Time complexity: O(log n) where n is the index + # Space complexity: O(1) only use constant sized variables def heap_up(index) until index == 0 || @store[index].key >= @store[((index - 1) / 2)].key parent = (index - 1) / 2