From 9598baa7aa92f0eabf03ba315b6a68b8024e1d06 Mon Sep 17 00:00:00 2001 From: Kelsey Krippaehne Date: Thu, 19 Mar 2020 21:15:36 -0700 Subject: [PATCH 1/3] implemented miniheap --- lib/minheap.js | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/lib/minheap.js b/lib/minheap.js index 4efceaf..52af2e8 100644 --- a/lib/minheap.js +++ b/lib/minheap.js @@ -14,7 +14,12 @@ class MinHeap { // Time Complexity: ? // Space Complexity: ? add(key, value = key) { - throw new Error("Method not implemented yet..."); + this.store.push(new HeapNode(key, value)); + if (this.store.length === 1) { + return + } else { + this.heapUp(this.store.length - 1) + } } // This method removes and returns an element from the heap @@ -22,7 +27,11 @@ class MinHeap { // Time Complexity: ? // Space Complexity: ? remove() { - throw new Error("Method not implemented yet..."); + if (this.isEmpty()) return; + this.swap(0, this.store.length - 1) + const removedNode = this.store.pop(); + this.heapDown(0); + return removedNode.value; } @@ -41,7 +50,7 @@ class MinHeap { // Time complexity: ? // Space complexity: ? isEmpty() { - throw new Error("Method not implemented yet..."); + return this.store.length === 0 } // This helper method takes an index and @@ -50,14 +59,43 @@ class MinHeap { // Time complexity: ? // Space complexity: ? heapUp(index) { - throw new Error("Method not implemented yet..."); + + const parent = Math.floor((index - 1) / 2); + if (this.store[parent].key > this.store[index].key) { + this.swap(parent, index); + // heap up until we hit the root + if (parent > 0) this.heapUp(parent); + } + } // This helper method takes an index and // moves it up the heap if it's smaller // than it's parent node. heapDown(index) { - throw new Error("Method not implemented yet..."); + + // got tired of writing out this.store + const store = this.store; + + if (index >= store.length) return; + + let leftChild = index * 2 + 1 + let rightChild = index * 2 + 2 + + // return if there is no left child node + if (store[leftChild] === undefined) { + return; + } + + // find smaller child node between left & right + let minChild = rightChild; + if (store[rightChild] === undefined || store[leftChild].key <= store[rightChild].key) minChild = leftChild + + // swap parent with smaller child + if (store[minChild].key < store[index].key) { + this.swap(minChild, index) + this.heapDown(minChild); + } } // If you want a swap method... you're welcome From dd97832efda98a0964fc000220ed8044be5fffdf Mon Sep 17 00:00:00 2001 From: Kelsey Krippaehne Date: Thu, 19 Mar 2020 22:20:45 -0700 Subject: [PATCH 2/3] implemented heapsort --- lib/heapsort.js | 14 ++++++++++++-- test/heapsort.test.js | 3 ++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/heapsort.js b/lib/heapsort.js index 69d5af2..4ec60b8 100644 --- a/lib/heapsort.js +++ b/lib/heapsort.js @@ -1,8 +1,18 @@ +const { MinHeap } = require('../lib/minheap'); // This method uses a heap to sort an array. // Time Complexity: ? // Space Complexity: ? function heapsort(list) { - throw new Error('Method not implemented yet...'); -}; + if (list.length <= 1) return list; + + const heap = new MinHeap(); + list.forEach(item => { + heap.add(item) + }) + for (let i = 0; i < list.length; i++) { + list[i] = heap.remove(); + } + return list; +} module.exports = heapsort; diff --git a/test/heapsort.test.js b/test/heapsort.test.js index a34282b..9f246e4 100644 --- a/test/heapsort.test.js +++ b/test/heapsort.test.js @@ -1,6 +1,7 @@ const expect = require('chai').expect; +const heapsort = require('../lib/heapsort') -describe.skip("heapsort", function() { +describe("heapsort", function() { it("sorts an empty array", function() { // Arrange const list = []; From ec33f694ab4cf8aee244a190240e07d92773f787 Mon Sep 17 00:00:00 2001 From: Kelsey Krippaehne Date: Thu, 19 Mar 2020 22:50:44 -0700 Subject: [PATCH 3/3] added time & spack complexities --- lib/heapsort.js | 9 +++++++-- lib/minheap.js | 32 +++++++++++++++++--------------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/lib/heapsort.js b/lib/heapsort.js index 4ec60b8..f4368b2 100644 --- a/lib/heapsort.js +++ b/lib/heapsort.js @@ -1,17 +1,22 @@ const { MinHeap } = require('../lib/minheap'); // This method uses a heap to sort an array. -// Time Complexity: ? -// Space Complexity: ? +// Time Complexity: O(n log n) - iterating over list (n) while running .add()/.remove() (both log n) +// Space Complexity: O(n), where n is length of list + function heapsort(list) { if (list.length <= 1) return list; const heap = new MinHeap(); + list.forEach(item => { heap.add(item) }) + for (let i = 0; i < list.length; i++) { + // rewriting the original list ♻️ list[i] = heap.remove(); } + return list; } diff --git a/lib/minheap.js b/lib/minheap.js index 52af2e8..c981cb4 100644 --- a/lib/minheap.js +++ b/lib/minheap.js @@ -11,12 +11,12 @@ class MinHeap { } // This method adds a HeapNode instance to the heap - // Time Complexity: ? - // Space Complexity: ? + // Time Complexity: O(log n), if we include the heapUp helper function + // Space Complexity: O(log n), because of the recursive heapUp stack add(key, value = key) { this.store.push(new HeapNode(key, value)); if (this.store.length === 1) { - return + return; } else { this.heapUp(this.store.length - 1) } @@ -24,8 +24,8 @@ class MinHeap { // 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(log n) remove() { if (this.isEmpty()) return; this.swap(0, this.store.length - 1) @@ -47,8 +47,8 @@ class MinHeap { } // This method returns true if the heap is empty - // Time complexity: ? - // Space complexity: ? + // Time complexity: O(1) of course! + // Space complexity: O(1). never felt more confident with space complexity. isEmpty() { return this.store.length === 0 } @@ -56,8 +56,8 @@ class MinHeap { // 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(log n) heapUp(index) { const parent = Math.floor((index - 1) / 2); @@ -72,27 +72,29 @@ class MinHeap { // 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(log n), because of the recursive stack heapDown(index) { - // got tired of writing out this.store - const store = this.store; + // to shorten code lines instead of writing out 'this.store' every time + const s = this.store; - if (index >= store.length) return; + if (index >= s.length) return; let leftChild = index * 2 + 1 let rightChild = index * 2 + 2 // return if there is no left child node - if (store[leftChild] === undefined) { + if (s[leftChild] === undefined) { return; } // find smaller child node between left & right let minChild = rightChild; - if (store[rightChild] === undefined || store[leftChild].key <= store[rightChild].key) minChild = leftChild + if (s[rightChild] === undefined || s[leftChild].key <= s[rightChild].key) minChild = leftChild // swap parent with smaller child - if (store[minChild].key < store[index].key) { + if (s[minChild].key < s[index].key) { this.swap(minChild, index) this.heapDown(minChild); }