From 7ae8edcfc89fce0bdefa26cbde3a2ded149641aa Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Thu, 6 May 2021 13:49:28 -0700 Subject: [PATCH 1/5] add and heap_sort with recursive helper implemented --- lib/heap_sort.rb | 33 +++++++++++++++++++++++++++++++-- lib/min_heap.rb | 9 ++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb index c8a32a4..0ca4f93 100644 --- a/lib/heap_sort.rb +++ b/lib/heap_sort.rb @@ -4,5 +4,34 @@ # Time Complexity: ? # Space Complexity: ? def heap_sort(list) - raise NotImplementedError, "Method not implemented yet..." -end \ No newline at end of file + # raise NotImplementedError, "Method not implemented yet..." + # left_child = i * 2 + 1 + # right_child = i * 2 + 2 + + + return heap_sort_helper(list, 0) + +end + + +def heap_sort_helper(list, i) + return if list[i].nil? + + heap_sort_helper(list, (i*2 + 1)) + heap_sort_helper(list, (i*2 + 2)) + + + if !list[(i*2 +1)].nil? && (list[i].key > list[(i*2 +1)].key) + temp = list[i] + list[i] = list[(i*2 +1)] + list[(i*2 +1)] = temp + end + + if !list[(i*2 +2)].nil? && list[i].key > list[(i*2 + 2)].key + temp = list[i] + list[i] = list[(i*2 + 2)] + list[(i*2 + 2)] = temp +end + +end + diff --git a/lib/min_heap.rb b/lib/min_heap.rb index 6eaa630..8a0f12a 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -17,7 +17,14 @@ def initialize # Time Complexity: ? # Space Complexity: ? def add(key, value = key) - raise NotImplementedError, "Method not implemented yet..." + # raise NotImplementedError, "Method not implemented yet..." + @store << HeapNode.new(key, value) + + + if @store.length > 1 + heap_sort(@store) + end + end # This method removes and returns an element from the heap From 0a7b6076c287420cbb583d602444c314f146f84d Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Thu, 6 May 2021 14:19:46 -0700 Subject: [PATCH 2/5] created heap up recursive method --- lib/heap_sort.rb | 5 ++--- lib/min_heap.rb | 28 +++++++++++++++++++++------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb index 0ca4f93..3dbcaf4 100644 --- a/lib/heap_sort.rb +++ b/lib/heap_sort.rb @@ -1,13 +1,12 @@ # This method uses a heap to sort an array. -# Time Complexity: ? -# Space Complexity: ? +# Time Complexity: O(n) - will go to every node to compare and heap up +# Space Complexity: O(n) - will have a call stack equal to number of nodes, though we are not makng a new data structure. def heap_sort(list) # raise NotImplementedError, "Method not implemented yet..." # left_child = i * 2 + 1 # right_child = i * 2 + 2 - return heap_sort_helper(list, 0) diff --git a/lib/min_heap.rb b/lib/min_heap.rb index 8a0f12a..914c6b2 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -14,15 +14,18 @@ def initialize end # This method adds a HeapNode instance to the heap - # Time Complexity: ? - # Space Complexity: ? + # Time Complexity: O(m+1), where m is height - O(1) for adding, O(m) for heap up + # Space Complexity: O(1) - no new data structures made, but O(m) for heap up call stack (is it the number of calls in the calls stack or number of structures made?) def add(key, value = key) - # raise NotImplementedError, "Method not implemented yet..." @store << HeapNode.new(key, value) - + # @store.each do |node| + # puts node.key + # end + + print @store[0].key if @store.length > 1 - heap_sort(@store) + heap_up(@store.length - 1) end end @@ -62,12 +65,23 @@ 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(m) where m is height + # Space complexity: O(1), no persistent data structure is made beyond 1 temporary reassigned variable def heap_up(index) + return if index == 0 + + if @store[index].key < @store[((index - (index % 3)) / 2)].key + temp = @store[index] + @store[index] = @store[((index - (index % 3)) / 2)] + @store[((index - (index % 3)) / 2)] = temp + end + + heap_up(((index - (index % 3)) / 2)) end + + # This helper method takes an index and # moves it up the heap if it's smaller # than it's parent node. From 2878b9d249755e4e7e23a7ce084752a279d7fe1f Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Wed, 12 May 2021 20:05:15 -0700 Subject: [PATCH 3/5] heap down implemented correctly, needed puts statements to see where error was, reversed less than and greater than signs --- lib/min_heap.rb | 57 ++++++++++++++++++++++++++++++++++++------- test/min_heap_test.rb | 40 +++++++++++++++--------------- 2 files changed, 68 insertions(+), 29 deletions(-) diff --git a/lib/min_heap.rb b/lib/min_heap.rb index 914c6b2..39fdbad 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -19,11 +19,6 @@ def initialize def add(key, value = key) @store << HeapNode.new(key, value) - # @store.each do |node| - # puts node.key - # end - - print @store[0].key if @store.length > 1 heap_up(@store.length - 1) end @@ -35,7 +30,38 @@ def add(key, value = key) # Time Complexity: ? # Space Complexity: ? def remove() - raise NotImplementedError, "Method not implemented yet..." + @store.each do |node| + puts "#{node.key} -- #{node.value}" + end + + swap(0, -1) + puts "***SWAPPED***" + @store.each do |node| + puts "#{node.key} -- #{node.value}" + end + + + + popped = @store.pop + + puts "popped -> #{popped.key} -- #{popped.value}" + + puts "after pop list" + @store.each do |node| + puts "#{node.key} -- #{node.value}" + end + heap_down(0) + + puts "after heap down" + @store.each do |node| + puts "#{node.key} -- #{node.value}" + end + + puts "BREAK BETWEEN FUNCTION CALLS" + return popped.value + + + end @@ -80,16 +106,29 @@ def heap_up(index) end - - # This helper method takes an index and # moves it up the heap if it's smaller # than it's parent node. + # left_child = i * 2 + 1 + # right_child = i * 2 + 2 def heap_down(index) - raise NotImplementedError, "Method not implemented yet..." + return if @store[index].nil? + + if !@store[index * 2 + 1].nil? && @store[index].key > @store[index * 2 + 1].key + swap(index, (index * 2 + 1)) + end + + if !@store[index * 2 + 2].nil? && @store[index].key > @store[index * 2 + 2].key + swap(index, (index * 2 + 2)) + end + + heap_down(index * 2 + 1) + heap_down(index * 2 + 2) + end # If you want a swap method... you're welcome + #THANK YOUUUUUU def swap(index_1, index_2) temp = @store[index_1] @store[index_1] = @store[index_2] diff --git a/test/min_heap_test.rb b/test/min_heap_test.rb index 186d4c2..ca4bb35 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" - end + # Another assert + expect(removed).must_equal "Pasta" + end end \ No newline at end of file From 3c05590f48dffdefb695d184bba03ad5929f99c3 Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Thu, 13 May 2021 21:56:37 -0700 Subject: [PATCH 4/5] heap sort implemented --- lib/heap_sort.rb | 31 +++++++++---------------------- lib/min_heap.rb | 42 ++++++++++++++++++++++++------------------ test/heapsort_test.rb | 8 ++++---- 3 files changed, 37 insertions(+), 44 deletions(-) diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb index 3dbcaf4..b54f20c 100644 --- a/lib/heap_sort.rb +++ b/lib/heap_sort.rb @@ -7,30 +7,17 @@ def heap_sort(list) # raise NotImplementedError, "Method not implemented yet..." # left_child = i * 2 + 1 # right_child = i * 2 + 2 + heap = MinHeap.new - return heap_sort_helper(list, 0) - -end - - -def heap_sort_helper(list, i) - return if list[i].nil? - - heap_sort_helper(list, (i*2 + 1)) - heap_sort_helper(list, (i*2 + 2)) - + list.each do |element| + heap.add(element) + end - if !list[(i*2 +1)].nil? && (list[i].key > list[(i*2 +1)].key) - temp = list[i] - list[i] = list[(i*2 +1)] - list[(i*2 +1)] = temp + sorted_list = [] + until heap.empty? + sorted_list.push(heap.remove) end - - if !list[(i*2 +2)].nil? && list[i].key > list[(i*2 + 2)].key - temp = list[i] - list[i] = list[(i*2 + 2)] - list[(i*2 + 2)] = temp -end -end + return sorted_list +end \ No newline at end of file diff --git a/lib/min_heap.rb b/lib/min_heap.rb index 39fdbad..ecdbd07 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -30,34 +30,34 @@ def add(key, value = key) # Time Complexity: ? # Space Complexity: ? def remove() - @store.each do |node| - puts "#{node.key} -- #{node.value}" - end + # @store.each do |node| + # puts "#{node.key} -- #{node.value}" + # end swap(0, -1) - puts "***SWAPPED***" - @store.each do |node| - puts "#{node.key} -- #{node.value}" - end + # puts "***SWAPPED***" + # @store.each do |node| + # puts "#{node.key} -- #{node.value}" + # end popped = @store.pop - puts "popped -> #{popped.key} -- #{popped.value}" + # puts "popped -> #{popped.key} -- #{popped.value}" - puts "after pop list" - @store.each do |node| - puts "#{node.key} -- #{node.value}" - end + # puts "after pop list" + # @store.each do |node| + # puts "#{node.key} -- #{node.value}" + # end heap_down(0) - puts "after heap down" - @store.each do |node| - puts "#{node.key} -- #{node.value}" - end + # puts "after heap down" + # @store.each do |node| + # puts "#{node.key} -- #{node.value}" + # end - puts "BREAK BETWEEN FUNCTION CALLS" + # puts "BREAK BETWEEN FUNCTION CALLS" return popped.value @@ -83,7 +83,13 @@ def to_s # Time complexity: ? # Space complexity: ? def empty? - raise NotImplementedError, "Method not implemented yet..." + + if @store.nil? || @store.length == 0 + return true + else + return false + end + end private diff --git a/test/heapsort_test.rb b/test/heapsort_test.rb index 34402ac..271e711 100644 --- a/test/heapsort_test.rb +++ b/test/heapsort_test.rb @@ -1,12 +1,12 @@ require_relative "test_helper" -xdescribe "heapsort" do +describe "heapsort" do it "sorts an empty array" do # Arrange list = [] # Act - result = heapsort(list) + result = heap_sort(list) # Assert expect(result).must_equal [] @@ -17,7 +17,7 @@ list = [5] # Act - result = heapsort(list) + result = heap_sort(list) # Assert expect(result).must_equal [5] @@ -28,7 +28,7 @@ list = [5, 27, 3, 16, -50] # Act - result = heapsort(list) + result = heap_sort(list) # Assert expect(result).must_equal [-50, 3, 5, 16, 27] From e5ae8c7def75ba79977d57f9905c6607fe653fa3 Mon Sep 17 00:00:00 2001 From: Mackenzie Date: Thu, 13 May 2021 22:27:39 -0700 Subject: [PATCH 5/5] time/space complexity --- lib/heap_sort.rb | 4 ++-- lib/min_heap.rb | 36 ++++-------------------------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb index b54f20c..4fbccbe 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: O(n) - will go to every node to compare and heap up -# Space Complexity: O(n) - will have a call stack equal to number of nodes, though we are not makng a new data structure. +# Time Complexity: O(m+n) +# Space Complexity: O(n) - will have a call stack equal to number of nodes, though we are make a constant number of data structures... maybe O(1) def heap_sort(list) # raise NotImplementedError, "Method not implemented yet..." # left_child = i * 2 + 1 diff --git a/lib/min_heap.rb b/lib/min_heap.rb index ecdbd07..86f1870 100644 --- a/lib/min_heap.rb +++ b/lib/min_heap.rb @@ -27,41 +27,13 @@ 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: O(n+1) + # Space Complexity: O(1) def remove() - # @store.each do |node| - # puts "#{node.key} -- #{node.value}" - # end - swap(0, -1) - # puts "***SWAPPED***" - # @store.each do |node| - # puts "#{node.key} -- #{node.value}" - # end - - - popped = @store.pop - - # puts "popped -> #{popped.key} -- #{popped.value}" - - # puts "after pop list" - # @store.each do |node| - # puts "#{node.key} -- #{node.value}" - # end heap_down(0) - - # puts "after heap down" - # @store.each do |node| - # puts "#{node.key} -- #{node.value}" - # end - - # puts "BREAK BETWEEN FUNCTION CALLS" return popped.value - - - end @@ -80,8 +52,8 @@ 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? if @store.nil? || @store.length == 0