From c0fe2a3f16e156d61f7f95d8b6121f5797ebbc40 Mon Sep 17 00:00:00 2001 From: Oleksii Trekhleb Date: Wed, 2 May 2018 20:41:13 +0300 Subject: [PATCH] Update Heap. --- src/data-structures/heap/MinHeap.js | 74 +++++++++++++++++++ .../heap/__test__/MinHeap.test.js | 16 ++++ 2 files changed, 90 insertions(+) diff --git a/src/data-structures/heap/MinHeap.js b/src/data-structures/heap/MinHeap.js index 6eb2d843..03ac243f 100644 --- a/src/data-structures/heap/MinHeap.js +++ b/src/data-structures/heap/MinHeap.js @@ -1,54 +1,100 @@ import Comparator from '../../utils/comparator/Comparator'; export default class MinHeap { + /** + * @param {Function} [comparatorFunction] + */ constructor(comparatorFunction) { // Array representation of the heap. this.heapContainer = []; this.compare = new Comparator(comparatorFunction); } + /** + * @param {number} parentIndex + * @return {number} + */ static getLeftChildIndex(parentIndex) { return (2 * parentIndex) + 1; } + /** + * @param {number} parentIndex + * @return {number} + */ static getRightChildIndex(parentIndex) { return (2 * parentIndex) + 2; } + /** + * @param {number} childIndex + * @return {number} + */ static getParentIndex(childIndex) { return Math.floor((childIndex - 1) / 2); } + /** + * @param {number} childIndex + * @return {boolean} + */ static hasParent(childIndex) { return this.getParentIndex(childIndex) >= 0; } + /** + * @param {number} parentIndex + * @return {boolean} + */ hasLeftChild(parentIndex) { return MinHeap.getLeftChildIndex(parentIndex) < this.heapContainer.length; } + /** + * @param {number} parentIndex + * @return {boolean} + */ hasRightChild(parentIndex) { return MinHeap.getRightChildIndex(parentIndex) < this.heapContainer.length; } + /** + * @param {number} parentIndex + * @return {*} + */ leftChild(parentIndex) { return this.heapContainer[MinHeap.getLeftChildIndex(parentIndex)]; } + /** + * @param {number} parentIndex + * @return {*} + */ rightChild(parentIndex) { return this.heapContainer[MinHeap.getRightChildIndex(parentIndex)]; } + /** + * @param {number} childIndex + * @return {*} + */ parent(childIndex) { return this.heapContainer[MinHeap.getParentIndex(childIndex)]; } + /** + * @param {number} indexOne + * @param {number} indexTwo + */ swap(indexOne, indexTwo) { const tmp = this.heapContainer[indexTwo]; this.heapContainer[indexTwo] = this.heapContainer[indexOne]; this.heapContainer[indexOne] = tmp; } + /** + * @return {*} + */ peek() { if (this.heapContainer.length === 0) { return null; @@ -57,6 +103,9 @@ export default class MinHeap { return this.heapContainer[0]; } + /** + * @return {*} + */ poll() { if (this.heapContainer.length === 0) { return null; @@ -75,11 +124,30 @@ export default class MinHeap { return item; } + /** + * @param {*} item + */ add(item) { this.heapContainer.push(item); this.heapifyUp(); } + /** + * @param {*} item + * @return {Number[]} + */ + findItem(item) { + const foundItemIndices = []; + + for (let itemIndex = 0; itemIndex < this.heapContainer.length; itemIndex += 1) { + if (this.compare.equal(item, this.heapContainer[itemIndex])) { + foundItemIndices.push(itemIndex); + } + } + + return foundItemIndices; + } + heapifyUp() { // Take last element (last in array or the bottom left in a tree) in // a heap container and lift him up until we find the parent element @@ -120,10 +188,16 @@ export default class MinHeap { } } + /** + * @return {boolean} + */ isEmpty() { return !this.heapContainer.length; } + /** + * @return {string} + */ toString() { return this.heapContainer.toString(); } diff --git a/src/data-structures/heap/__test__/MinHeap.test.js b/src/data-structures/heap/__test__/MinHeap.test.js index 6dc7c162..15c44d07 100644 --- a/src/data-structures/heap/__test__/MinHeap.test.js +++ b/src/data-structures/heap/__test__/MinHeap.test.js @@ -88,4 +88,20 @@ describe('MinHeap', () => { expect(minHeap.poll()).toBe(3); expect(minHeap.toString()).toBe('10,11,12'); }); + + it('should be possible to find item indices in heap', () => { + const minHeap = new MinHeap(); + + minHeap.add(3); + minHeap.add(12); + minHeap.add(10); + minHeap.add(11); + minHeap.add(11); + + expect(minHeap.toString()).toBe('3,11,10,12,11'); + + expect(minHeap.findItem(5)).toEqual([]); + expect(minHeap.findItem(3)).toEqual([0]); + expect(minHeap.findItem(11)).toEqual([1, 4]); + }); });