diff --git a/lib/heap_sort.rb b/lib/heap_sort.rb
index c8a32a4..779c289 100644
--- a/lib/heap_sort.rb
+++ b/lib/heap_sort.rb
@@ -1,8 +1,98 @@
 
 
 # This method uses a heap to sort an array.
-# Time Complexity:  ?
-# Space Complexity: ?
-def heap_sort(list)
-  raise NotImplementedError, "Method not implemented yet..."
-end
\ No newline at end of file
+# Time Complexity:  O(nlogn)
+# Space Complexity: O(n)
+def heapsort(list)
+  heapify(list, parent(list.length - 1)) if list.length > 1
+  sort_heaped_list(list)
+  return list
+end
+
+private 
+# Time Complexity:  O(nlog(n))
+# Space Complexity: O(1) 
+def sort_heaped_list(list)
+  last_pos = list.length - 1
+  while last_pos > 0
+    remove_max(list, last_pos)
+    last_pos -= 1
+  end
+end
+
+# Time Complexity:  O(log(n))
+# Space Complexity: O(1)
+def remove_max(list, last_pos)
+  removed = list[0]
+  list[0] = list[last_pos] 
+  list[last_pos] = removed
+  heap_down(0, last_pos - 1, list)
+end
+
+# Time Complexity:  O(log(n))
+# Space Complexity: O(1)
+def heap_down(sub_root, last_pos, list)
+  max_child = max_child(right_child(sub_root, last_pos), left_child(sub_root, last_pos), list)
+  while max_child && list[max_child] > list[sub_root]
+    swap(sub_root, max_child, list)
+    sub_root = max_child
+    max_child = max_child(right_child(sub_root, last_pos), left_child(sub_root, last_pos), list)
+  end
+end
+
+# Time Complexity:  O(n)  => this is based of the math proof on geeks for geeks, not sure if I 100 % understand ... yet
+# Space Complexity: O(n) <= can optimize by using iterative approach over recursion
+def heapify(list, sub_root, counter = 0)
+  max_child = max_child(right_child(sub_root, list.length), left_child(sub_root, list.length), list)
+  if max_child && list[max_child] > list[sub_root]
+    swap(max_child, sub_root, list)
+    heapify(list, max_child, counter + 1)
+  elsif max_child
+    heapify(list, sub_root - 1, counter + 1)
+  end 
+  return 
+end
+
+
+# Time Complexity:  O(1)
+# Space Complexity: O(1)
+def swap(index1, index2, list)
+  temp = list[index1]
+  list[index1] = list[index2]
+  list[index2] = temp
+end
+
+# Time Complexity:  O(1)
+# Space Complexity: O(1)
+def max_child(left, right, list)
+  if !right || !left || list[left] > list[right]
+    return left
+  end
+  return right
+end
+
+# Time Complexity:  O(1)
+# Space Complexity: O(1)
+def parent(child)
+  return (child - 1) / 2
+end
+
+# Time Complexity:  O(1)
+# Space Complexity: O(1)
+def right_child(root, length)
+  child = root * 2 + 2
+  if child < length
+    return child
+  end
+  return
+end
+
+# Time Complexity:  O(1)
+# Space Complexity: O(1)
+def left_child(root, length)
+  child = root * 2 + 1
+  if child < length
+    return child
+  end
+  return
+end
diff --git a/lib/min_heap.rb b/lib/min_heap.rb
index 6eaa630..74b81c9 100644
--- a/lib/min_heap.rb
+++ b/lib/min_heap.rb
@@ -14,18 +14,22 @@ def initialize
   end
 
   # This method adds a HeapNode instance to the heap
-  # Time Complexity: ?
-  # Space Complexity: ?
+  # Time Complexity: O(log(n))
+  # Space Complexity: 0(1)
   def add(key, value = key)
-    raise NotImplementedError, "Method not implemented yet..."
+    @store << 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(1)
   def remove()
-    raise NotImplementedError, "Method not implemented yet..."
+    removed = @store[0]
+    @store[0] = @store.pop 
+    heap_down(0)
+    return removed.value
   end
 
 
@@ -44,10 +48,10 @@ def to_s
   end
 
   # This method returns true if the heap is empty
-  # Time complexity: ?
-  # Space complexity: ?
+  # Time complexity: O(1) assuming ruby implements array with memotized length ie attribute of array class rather than method
+  # Space complexity: O(1)
   def empty?
-    raise NotImplementedError, "Method not implemented yet..."
+    return @store.empty?
   end
 
   private
@@ -55,17 +59,62 @@ 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))
+  # Space complexity: O(1)
   def heap_up(index)
-    
+    parent_i =  parent_index(index)
+    until index == 0 || @store[parent_i].key < @store[index].key 
+      swap(parent_i, index)
+      index = parent_i
+      parent_i = parent_index(index)
+    end
+  end
+
+  def parent_index(index)
+    return (index - 1) / 2
   end
 
   # This helper method takes an index and 
   #  moves it up the heap if it's smaller
   #  than it's parent node.
+  # Time complexity: O(log(n))
+  # Space complexity: O(1)
   def heap_down(index)
-    raise NotImplementedError, "Method not implemented yet..."
+    right_child_i = right_child_index(index)
+    left_child_i = left_child_index(index)
+    until heaped_down_valid(left_child_i, right_child_i, index)
+      pos_to_swap = index_of_smallest_child_key(left_child_i, right_child_i)
+      swap(pos_to_swap, index)
+      index = pos_to_swap
+      right_child_i = right_child_index(index)
+      left_child_i = left_child_index(index)
+    end
+  end
+
+  def heaped_down_valid(left_child_i, right_child_i, index)
+    return !left_child_i || @store[left_child_i].key > @store[index].key && (right_child_i && @store[right_child_i].key > @store[index].key)
+  end
+
+  def index_of_smallest_child_key(index1,  index2)
+    if !index2 || @store[index2].key > @store[index1].key
+      return index1
+    else  
+      return index2
+    end
+  end
+
+  def right_child_index(index)
+    if index * 2 + 2 <=  @store.length - 1
+      return  index * 2 + 2
+    end
+    return
+  end
+
+  def left_child_index(index)
+    if index * 2 + 1 <= @store.length - 1
+      return  index * 2 + 1
+    end
+    return
   end
 
   # If you want a swap method... you're welcome
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 = []