From 6c1d8c76b4ca9985964c4505d560e8cd17124902 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Mon, 25 Nov 2019 12:07:41 +1100 Subject: [PATCH 01/20] removed unknown rule in .eslintrc.json --- .eslintrc.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index f94493c..9db8fd5 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,7 +16,6 @@ "rules": { "eqeqeq": "off", "curly": "error", - "quotes": ["error", "single"], - "allowImplicit": true + "quotes": ["error", "single"] } } From f1a0f972db2b82085a9424b66b8720654395b4fd Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Mon, 25 Nov 2019 12:08:08 +1100 Subject: [PATCH 02/20] skeleton code for Heap --- src/dataStructures/Heap.js | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/dataStructures/Heap.js diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js new file mode 100644 index 0000000..0c02e19 --- /dev/null +++ b/src/dataStructures/Heap.js @@ -0,0 +1,42 @@ +class Heap { + constructor(size = 15, isMax = 1) { + this._storage = new Array(size + 1); // 'size' items and one shift item to make calculations easier + this._sizeCounter = 3; // size = 2^this._sizeCounter - 1 + this._last = null; // points to the last item in the heap + this._isMax = isMax; // Max Heap or Min Heap + } + + _rise(item_index) { + + } + + _fall(item_index) { + + } + + isEmpty() { + + } + + isFull() { + + } + + increaseSize() { + this._storage = new Array(Math.pow(2, ++this._sizeCounter)); + } + + getTop() { + + } + + peek() { + + } + + push(item) { + + } +} + +module.exports = Heap; From cb711d8788b9f371c674d98af46c7366455a26eb Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 16:09:13 +1100 Subject: [PATCH 03/20] Test for constructor --- test/dataStructures/Heap.test.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 test/dataStructures/Heap.test.js diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js new file mode 100644 index 0000000..20e71bc --- /dev/null +++ b/test/dataStructures/Heap.test.js @@ -0,0 +1,8 @@ +const Heap = require('../../src/dataStructures/Heap'); + +describe('Heap data structure', () => { + it('should have empty heap when instantiated', () => { + const heap = new Heap(3); + expect(heap._storage).toEqual([undefined, undefined, undefined, undefined]); + }); +}); From 8fef6440099d1ad0bdaf9ae60ecb56ed439a9975 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 16:33:55 +1100 Subject: [PATCH 04/20] tests for rise method --- test/dataStructures/Heap.test.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index 20e71bc..7a7b894 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -6,3 +6,31 @@ describe('Heap data structure', () => { expect(heap._storage).toEqual([undefined, undefined, undefined, undefined]); }); }); + +describe('Heap private method rise', () => { + it('should move large items up for max Heap', () => { + const heap = new Heap(3, true); + heap._storage[1] = 1; + heap._storage[2] = 2; + heap._storage[3] = 3; + heap._rise(1); + expect(heap._storage).toEqual([undefined, 1, 2, 3]); + heap._rise(2); + expect(heap._storage).toEqual([undefined, 2, 1, 3]); + heap._rise(3); + expect(heap._storage).toEqual([undefined, 3, 1, 2]); + }); + + it('should move small items up for min Heap', () => { + const heap = new Heap(3, false); + heap._storage[1] = 3; + heap._storage[2] = 2; + heap._storage[3] = 1; + heap._rise(1); + expect(heap._storage).toEqual([undefined, 3, 2, 1]); + heap._rise(2); + expect(heap._storage).toEqual([undefined, 2, 3, 1]); + heap._rise(3); + expect(heap._storage).toEqual([undefined, 1, 3, 2]); + }); +}); From 9606a834df9d8650b34b7a2addde006f35f2f1fa Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 16:34:37 +1100 Subject: [PATCH 05/20] rise method --- src/dataStructures/Heap.js | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 0c02e19..8c268b1 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -6,11 +6,38 @@ class Heap { this._isMax = isMax; // Max Heap or Min Heap } - _rise(item_index) { + /** + * Swaps items + * + * @param {Number} i1 + * @param {Number} i2 + * @returns {void} + */ + _swap(i1, i2) { + [this._storage[i1], this._storage[i2]] = [this._storage[i2], this._storage[i1]]; + } + /** + * Moves item up the heap to the correct position + * + * @param {Number} index + * @returns {void} + */ + _rise(index) { + while (index > 1) { + let parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 + // swap if < for max heap, > for min heap + if ( + (this._isMax && this._storage[parentIndex] < this._storage[index]) // max heap + || (!this._isMax && this._storage[parentIndex] > this._storage[index]) // min heap + ) { + this._swap(parentIndex, index) + } + index = parentIndex; + } } - _fall(item_index) { + _fall(index) { } From 8f07121f9ae3578863388600da69d415e75a5050 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 17:07:08 +1100 Subject: [PATCH 06/20] heap is now only max heap --- src/dataStructures/Heap.js | 22 ++++++++++++++-------- test/dataStructures/Heap.test.js | 17 ++--------------- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 8c268b1..b9eaf05 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -1,9 +1,8 @@ class Heap { - constructor(size = 15, isMax = 1) { + constructor(size = 15) { this._storage = new Array(size + 1); // 'size' items and one shift item to make calculations easier this._sizeCounter = 3; // size = 2^this._sizeCounter - 1 this._last = null; // points to the last item in the heap - this._isMax = isMax; // Max Heap or Min Heap } /** @@ -25,20 +24,27 @@ class Heap { */ _rise(index) { while (index > 1) { - let parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 + const parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 // swap if < for max heap, > for min heap - if ( - (this._isMax && this._storage[parentIndex] < this._storage[index]) // max heap - || (!this._isMax && this._storage[parentIndex] > this._storage[index]) // min heap - ) { + if (this._storage[parentIndex] < this._storage[index]) { this._swap(parentIndex, index) } index = parentIndex; } } + /** + * Moves item down the heap to the correct position + * + * @param {Number} index + * @returns {void} + */ _fall(index) { - + while (index < this._storage.length) { + const c1 = 2*index; // left child + const c2 = 2*index + 1; // right child + let childIndex; + } } isEmpty() { diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index 7a7b894..6f6a208 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -8,8 +8,8 @@ describe('Heap data structure', () => { }); describe('Heap private method rise', () => { - it('should move large items up for max Heap', () => { - const heap = new Heap(3, true); + it('should move large items up', () => { + const heap = new Heap(3); heap._storage[1] = 1; heap._storage[2] = 2; heap._storage[3] = 3; @@ -20,17 +20,4 @@ describe('Heap private method rise', () => { heap._rise(3); expect(heap._storage).toEqual([undefined, 3, 1, 2]); }); - - it('should move small items up for min Heap', () => { - const heap = new Heap(3, false); - heap._storage[1] = 3; - heap._storage[2] = 2; - heap._storage[3] = 1; - heap._rise(1); - expect(heap._storage).toEqual([undefined, 3, 2, 1]); - heap._rise(2); - expect(heap._storage).toEqual([undefined, 2, 3, 1]); - heap._rise(3); - expect(heap._storage).toEqual([undefined, 1, 3, 2]); - }); }); From c16053675e7f1548c66e8e79d920afc29d3fc7c7 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 17:21:15 +1100 Subject: [PATCH 07/20] made rise method recursive --- src/dataStructures/Heap.js | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index b9eaf05..456e88c 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -1,4 +1,16 @@ class Heap { + /** + * Constructor for Heap data structure. + * + * This is a max Heap supported by an Array. This can be modified into a min Heap + * by changing '>' to '<' and '<' to '>'. + * + * @class + * + * @param {Number} i1 + * @param {Number} i2 + * @returns {void} + */ constructor(size = 15) { this._storage = new Array(size + 1); // 'size' items and one shift item to make calculations easier this._sizeCounter = 3; // size = 2^this._sizeCounter - 1 @@ -23,13 +35,12 @@ class Heap { * @returns {void} */ _rise(index) { - while (index > 1) { - const parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 - // swap if < for max heap, > for min heap - if (this._storage[parentIndex] < this._storage[index]) { - this._swap(parentIndex, index) - } - index = parentIndex; + if (index === 1) { return; } // base case + const parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 + // swap if < for max heap, > for min heap + if (this._storage[parentIndex] < this._storage[index]) { + this._swap(parentIndex, index); + this._rise(parentIndex); } } @@ -40,11 +51,7 @@ class Heap { * @returns {void} */ _fall(index) { - while (index < this._storage.length) { - const c1 = 2*index; // left child - const c2 = 2*index + 1; // right child - let childIndex; - } + } isEmpty() { From c2e80b9f2a798b497ebcec732f3d67785e42d36b Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 17:27:39 +1100 Subject: [PATCH 08/20] no longer preallocates supporting array modified tests to reflect change --- src/dataStructures/Heap.js | 11 +++-------- test/dataStructures/Heap.test.js | 15 +++++++++++---- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 456e88c..0fd305d 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -11,9 +11,8 @@ class Heap { * @param {Number} i2 * @returns {void} */ - constructor(size = 15) { - this._storage = new Array(size + 1); // 'size' items and one shift item to make calculations easier - this._sizeCounter = 3; // size = 2^this._sizeCounter - 1 + constructor() { + this._storage = new Array(1); this._last = null; // points to the last item in the heap } @@ -35,7 +34,7 @@ class Heap { * @returns {void} */ _rise(index) { - if (index === 1) { return; } // base case + if (index === 1) { return; } // base case : top item const parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 // swap if < for max heap, > for min heap if (this._storage[parentIndex] < this._storage[index]) { @@ -62,10 +61,6 @@ class Heap { } - increaseSize() { - this._storage = new Array(Math.pow(2, ++this._sizeCounter)); - } - getTop() { } diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index 6f6a208..5df0852 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -2,19 +2,26 @@ const Heap = require('../../src/dataStructures/Heap'); describe('Heap data structure', () => { it('should have empty heap when instantiated', () => { - const heap = new Heap(3); - expect(heap._storage).toEqual([undefined, undefined, undefined, undefined]); + const heap = new Heap(); + expect(heap._storage).toEqual([undefined]); }); }); describe('Heap private method rise', () => { - it('should move large items up', () => { - const heap = new Heap(3); + it('should not move items in the correct position', () => { + const heap = new Heap(); heap._storage[1] = 1; heap._storage[2] = 2; heap._storage[3] = 3; heap._rise(1); expect(heap._storage).toEqual([undefined, 1, 2, 3]); + }); + + it('should move large items up', () => { + const heap = new Heap(); + heap._storage[1] = 1; + heap._storage[2] = 2; + heap._storage[3] = 3; heap._rise(2); expect(heap._storage).toEqual([undefined, 2, 1, 3]); heap._rise(3); From c83c95ebd7bf6736a87fc8d6f03e21e7f447a569 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 17:46:36 +1100 Subject: [PATCH 09/20] added tests for fall method --- test/dataStructures/Heap.test.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index 5df0852..f36a09e 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -28,3 +28,23 @@ describe('Heap private method rise', () => { expect(heap._storage).toEqual([undefined, 3, 1, 2]); }); }); + +describe('Heap private method fall', () => { + it('should not move items in the correct position', () => { + const heap = new Heap(); + heap._storage[1] = 4; + heap._storage[2] = 2; + heap._storage[3] = 3; + heap._fall(1); + expect(heap._storage).toEqual([undefined, 4, 2, 3]); + }); + + it('should move small items down', () => { + const heap = new Heap(); + heap._storage[1] = 1; + heap._storage[2] = 2; + heap._storage[3] = 3; + heap._fall(1); + expect(heap._storage).toEqual([undefined, 3, 2, 1]); + }); +}); From b19c831ac4ec2ff3f69453b38350ce5f89837bcb Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 17:50:26 +1100 Subject: [PATCH 10/20] added test cases for rise and fall methods --- test/dataStructures/Heap.test.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index f36a09e..ee4cbb6 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -8,13 +8,21 @@ describe('Heap data structure', () => { }); describe('Heap private method rise', () => { - it('should not move items in the correct position', () => { + it('should not move top item', () => { const heap = new Heap(); heap._storage[1] = 1; heap._storage[2] = 2; - heap._storage[3] = 3; heap._rise(1); - expect(heap._storage).toEqual([undefined, 1, 2, 3]); + expect(heap._storage).toEqual([undefined, 1, 2]); + }); + + it('should not move items in the correct position', () => { + const heap = new Heap(); + heap._storage[1] = 2; + heap._storage[2] = 1; + heap._storage[3] = 3; + heap._rise(2); + expect(heap._storage).toEqual([undefined, 2, 1, 3]); }); it('should move large items up', () => { @@ -30,6 +38,15 @@ describe('Heap private method rise', () => { }); describe('Heap private method fall', () => { + it('should not move items with no children', () => { + const heap = new Heap(); + heap._storage[1] = 1; + heap._storage[2] = 2; + heap._storage[3] = 3; + heap._fall(3); + expect(heap._storage).toEqual([undefined, 1, 2, 3]); + }); + it('should not move items in the correct position', () => { const heap = new Heap(); heap._storage[1] = 4; From 6964c59b3c0850311fd67c020ab1570a0bee28e8 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 17:51:27 +1100 Subject: [PATCH 11/20] added fall method; small fixes to documentation docs fixes: - added missing periods - removed unnecessary spaces --- src/dataStructures/Heap.js | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 0fd305d..943b467 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -3,7 +3,7 @@ class Heap { * Constructor for Heap data structure. * * This is a max Heap supported by an Array. This can be modified into a min Heap - * by changing '>' to '<' and '<' to '>'. + * by swapping the item comparisons. * * @class * @@ -17,7 +17,7 @@ class Heap { } /** - * Swaps items + * Swaps items. * * @param {Number} i1 * @param {Number} i2 @@ -28,13 +28,13 @@ class Heap { } /** - * Moves item up the heap to the correct position + * Moves item up the heap to the correct position. * * @param {Number} index * @returns {void} */ _rise(index) { - if (index === 1) { return; } // base case : top item + if (index === 1) { return; } // base case: top item const parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 // swap if < for max heap, > for min heap if (this._storage[parentIndex] < this._storage[index]) { @@ -44,13 +44,22 @@ class Heap { } /** - * Moves item down the heap to the correct position + * Moves item down the heap to the correct position. * * @param {Number} index * @returns {void} */ _fall(index) { - + if (2*index >= this._storage.length) { return; } // base case: no children + const childIndex = 2*index+1 >= this._storage.length ? + 2*index // one child (left) + : this._storage[2*index] > this._storage[2*index+1] ? // two children + 2*index + : 2*index+1; // compare with largest child + if (this._storage[childIndex] > this._storage[index]) { + this._swap(childIndex, index); + this._fall(childIndex); + } } isEmpty() { From 73160beeabec9f00e0590a367ff31371a7d9772b Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 17:54:34 +1100 Subject: [PATCH 12/20] swapped order of peek and getTop methods --- src/dataStructures/Heap.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 943b467..22db6de 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -70,11 +70,11 @@ class Heap { } - getTop() { + peek() { } - peek() { + getTop() { } From 9a9d9e6abe864ee7b2c0d577790b2c07f5b22d05 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 18:13:01 +1100 Subject: [PATCH 13/20] added isEmpty and peek methods; modified docs docs: - specified that Heap is intended for Number items - changed test descriptions to be for the constructor rather than data structure --- src/dataStructures/Heap.js | 23 ++++++++++++++------- test/dataStructures/Heap.test.js | 34 ++++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 22db6de..3837bc1 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -3,7 +3,8 @@ class Heap { * Constructor for Heap data structure. * * This is a max Heap supported by an Array. This can be modified into a min Heap - * by swapping the item comparisons. + * by swapping the item comparisons. The Heap is intended for Number items, but can be + * modified for any item. * * @class * @@ -62,16 +63,24 @@ class Heap { } } + /** + * Returns true if there are no items in the Heap, otherwise false. + * + * @returns {Boolean} + */ isEmpty() { - - } - - isFull() { - + return this._storage.length === 1; } + /** + * Returns the top item in Heap. + * + * If the Heap is empty, returns undefined. + * + * @returns {Number} + */ peek() { - + return this._storage[1]; } getTop() { diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index ee4cbb6..2cebcc2 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -1,12 +1,42 @@ const Heap = require('../../src/dataStructures/Heap'); -describe('Heap data structure', () => { - it('should have empty heap when instantiated', () => { +describe('Heap constructor', () => { + it('should create empty Heap', () => { const heap = new Heap(); expect(heap._storage).toEqual([undefined]); }); }); +describe('Heap public method isEmpty', () => { + it('should return true if no items in Heap', () => { + const heap = new Heap(); + expect(heap.isEmpty()).toBeTrue(); + }); + + it('should return false if one or more items in Heap', () => { + const heap = new Heap(); + heap._storage[1] = 1; + expect(heap.isEmpty()).toBeFalse(); + heap._storage[2] = 1; + expect(heap.isEmpty()).toBeFalse(); + }); +}); + +describe('Heap public method peek', () => { + it('should return undefined if Heap is empty', () => { + const heap = new Heap(); + expect(heap.peek()).toBeUndefined(); + }); + + it('should return the top item', () => { + const heap = new Heap(); + heap._storage[1] = 1; + heap._storage[2] = 2; + heap._storage[3] = 3; + expect(heap.peek()).toBe(1); + }); +}); + describe('Heap private method rise', () => { it('should not move top item', () => { const heap = new Heap(); From 52f8d2d75bfab502a4d01c406c011e040529669e Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 20:26:24 +1100 Subject: [PATCH 14/20] added getMax method and tests --- src/dataStructures/Heap.js | 15 +++++++++++++-- test/dataStructures/Heap.test.js | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 3837bc1..7bdedcd 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -83,8 +83,19 @@ class Heap { return this._storage[1]; } - getTop() { - + /** + * Returns and removes the top item in Heap. + * + * If the Heap is empty, returns undefined. + * + * @returns {Number} + */ + getMax() { + if (this.isEmpty()) { return; } + this._swap(1, this._storage.length-1); // swap top item and last item + const top = this._storage.pop(); + this._fall(1); + return top; } push(item) { diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index 2cebcc2..f6d4663 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -37,6 +37,23 @@ describe('Heap public method peek', () => { }); }); +describe('Heap public method getMax', () => { + it('should return undefined if Heap is empty', () => { + const heap = new Heap(); + expect(heap.getMax()).toBeUndefined(); + }); + + it('should return and remove the top item', () => { + const heap = new Heap(); + heap._storage[1] = 3; + heap._storage[2] = 2; + heap._storage[3] = 1; + const top = heap.getMax(); + expect(top).toBe(3); + expect(heap._storage).toEqual([undefined, 2, 1]); + }); +}); + describe('Heap private method rise', () => { it('should not move top item', () => { const heap = new Heap(); From 1542e7eb64664b869cb74473f115125d7dcdde47 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sat, 30 Nov 2019 21:06:08 +1100 Subject: [PATCH 15/20] added length accessor and tests --- src/dataStructures/Heap.js | 9 +++++++++ test/dataStructures/Heap.test.js | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index 7bdedcd..ded4233 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -17,6 +17,15 @@ class Heap { this._last = null; // points to the last item in the heap } + /** + * Returns number of items in Heap. + * + * @returns {Number} + */ + get length() { + return this._storage.length-1; + } + /** * Swaps items. * diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index f6d4663..e152cec 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -54,6 +54,21 @@ describe('Heap public method getMax', () => { }); }); +describe('Heap public method count', () => { + it('should return 0 for no items', () => { + const heap = new Heap(); + expect(heap.length).toBe(0); + }); + + it('should return the number of items in Heap', () => { + const heap = new Heap(); + heap._storage[1] = 2; + expect(heap.length).toBe(1); + heap._storage[2] = 1; + expect(heap.length).toBe(2); + }); +}); + describe('Heap private method rise', () => { it('should not move top item', () => { const heap = new Heap(); From 5018b98f32dbccf7f3cc4477fb46142807b705d8 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sun, 1 Dec 2019 02:14:26 +1100 Subject: [PATCH 16/20] added push method and tests --- src/dataStructures/Heap.js | 8 +++++++- test/dataStructures/Heap.test.js | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index ded4233..a1eefe2 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -107,8 +107,14 @@ class Heap { return top; } + /** + * Adds an item to the Heap. + * + * @returns {void} + */ push(item) { - + this._storage.push(item); + this._rise(this._storage.length-1); } } diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index e152cec..7634439 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -69,6 +69,25 @@ describe('Heap public method count', () => { }); }); +describe('Heap public method push', () => { + it('should increase the number of items in the Heap', () => { + const heap = new Heap(); + expect(heap.length).toBe(0); + heap.push(1); + expect(heap.length).toBe(1); + }); + + it('should add items in the correct position', () => { + const heap = new Heap(); + heap.push(1); + expect(heap._storage).toEqual([undefined, 1]); + heap.push(2); + expect(heap._storage).toEqual([undefined, 2, 1]); + heap.push(3); + expect(heap._storage).toEqual([undefined, 3, 1, 2]) + }); +}); + describe('Heap private method rise', () => { it('should not move top item', () => { const heap = new Heap(); From ddf9e35d28786511d7cc4daf71e920e1605ad85d Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sun, 1 Dec 2019 02:24:06 +1100 Subject: [PATCH 17/20] changed storage property to be more private Heap.prototype._storage descriptor: { value: new Array(1), enumerable: false, writable: false, configurable: false } --- src/dataStructures/Heap.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index a1eefe2..cb4ca86 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -13,8 +13,9 @@ class Heap { * @returns {void} */ constructor() { - this._storage = new Array(1); - this._last = null; // points to the last item in the heap + Object.defineProperty(this, '_storage', { + value: new Array(1) + }); } /** From d960193362b23d54b37093c77ef63947968b7de1 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sun, 1 Dec 2019 02:28:07 +1100 Subject: [PATCH 18/20] modified README.md to link to Heap.js relates to #118 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a73a809..3d5fff5 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ This repository maintained by [Nick Scialli](https://twitter.com/nas5w) and powe - TODO: Binary Tree - [Graph](/src/dataStructures/graph.js) - [Hash Table](/src/dataStructures/hashTable.js) -- TODO: Heap +- [Heap](/src/dataStructures/Heap.js) - TODO: Tree - TODO: Graph - TODO: Disjoint Set From 2f6bd94a9b7ff2ca870374e6dcc2ee340da32315 Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sun, 1 Dec 2019 02:31:26 +1100 Subject: [PATCH 19/20] indentation for documentation is more consistent --- src/dataStructures/Heap.js | 108 ++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/src/dataStructures/Heap.js b/src/dataStructures/Heap.js index cb4ca86..0c39976 100644 --- a/src/dataStructures/Heap.js +++ b/src/dataStructures/Heap.js @@ -1,17 +1,17 @@ class Heap { - /** - * Constructor for Heap data structure. - * - * This is a max Heap supported by an Array. This can be modified into a min Heap - * by swapping the item comparisons. The Heap is intended for Number items, but can be - * modified for any item. - * - * @class - * - * @param {Number} i1 - * @param {Number} i2 - * @returns {void} - */ + /** + * Constructor for Heap data structure. + * + * This is a max Heap supported by an Array. This can be modified into a min Heap + * by swapping the item comparisons. The Heap is intended for Number items, but can be + * modified for any item. + * + * @class + * + * @param {Number} i1 + * @param {Number} i2 + * @returns {void} + */ constructor() { Object.defineProperty(this, '_storage', { value: new Array(1) @@ -19,31 +19,31 @@ class Heap { } /** - * Returns number of items in Heap. - * - * @returns {Number} - */ + * Returns number of items in Heap. + * + * @returns {Number} + */ get length() { return this._storage.length-1; } /** - * Swaps items. - * - * @param {Number} i1 - * @param {Number} i2 - * @returns {void} - */ + * Swaps items. + * + * @param {Number} i1 + * @param {Number} i2 + * @returns {void} + */ _swap(i1, i2) { [this._storage[i1], this._storage[i2]] = [this._storage[i2], this._storage[i1]]; } - /** - * Moves item up the heap to the correct position. - * - * @param {Number} index - * @returns {void} - */ + /** + * Moves item up the heap to the correct position. + * + * @param {Number} index + * @returns {void} + */ _rise(index) { if (index === 1) { return; } // base case: top item const parentIndex = Math.floor(index/2); // child items are 2*index and 2*index + 1 @@ -55,11 +55,11 @@ class Heap { } /** - * Moves item down the heap to the correct position. - * - * @param {Number} index - * @returns {void} - */ + * Moves item down the heap to the correct position. + * + * @param {Number} index + * @returns {void} + */ _fall(index) { if (2*index >= this._storage.length) { return; } // base case: no children const childIndex = 2*index+1 >= this._storage.length ? @@ -74,32 +74,32 @@ class Heap { } /** - * Returns true if there are no items in the Heap, otherwise false. - * - * @returns {Boolean} - */ + * Returns true if there are no items in the Heap, otherwise false. + * + * @returns {Boolean} + */ isEmpty() { return this._storage.length === 1; } /** - * Returns the top item in Heap. - * - * If the Heap is empty, returns undefined. - * - * @returns {Number} - */ + * Returns the top item in Heap. + * + * If the Heap is empty, returns undefined. + * + * @returns {Number} + */ peek() { return this._storage[1]; } /** - * Returns and removes the top item in Heap. - * - * If the Heap is empty, returns undefined. - * - * @returns {Number} - */ + * Returns and removes the top item in Heap. + * + * If the Heap is empty, returns undefined. + * + * @returns {Number} + */ getMax() { if (this.isEmpty()) { return; } this._swap(1, this._storage.length-1); // swap top item and last item @@ -109,10 +109,10 @@ class Heap { } /** - * Adds an item to the Heap. - * - * @returns {void} - */ + * Adds an item to the Heap. + * + * @returns {void} + */ push(item) { this._storage.push(item); this._rise(this._storage.length-1); From 4e347bef05024afab59a97b7e419ae9b93d6684e Mon Sep 17 00:00:00 2001 From: Nick Wang Date: Sun, 1 Dec 2019 02:51:59 +1100 Subject: [PATCH 20/20] fixed test matcher name --- test/dataStructures/Heap.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/dataStructures/Heap.test.js b/test/dataStructures/Heap.test.js index 7634439..7ae2fb7 100644 --- a/test/dataStructures/Heap.test.js +++ b/test/dataStructures/Heap.test.js @@ -10,15 +10,15 @@ describe('Heap constructor', () => { describe('Heap public method isEmpty', () => { it('should return true if no items in Heap', () => { const heap = new Heap(); - expect(heap.isEmpty()).toBeTrue(); + expect(heap.isEmpty()).toBe(true); }); it('should return false if one or more items in Heap', () => { const heap = new Heap(); heap._storage[1] = 1; - expect(heap.isEmpty()).toBeFalse(); + expect(heap.isEmpty()).toBe(false); heap._storage[2] = 1; - expect(heap.isEmpty()).toBeFalse(); + expect(heap.isEmpty()).toBe(false); }); });