From 2cb42d466cbb2e0b07f7bda8a18ef7a007a08533 Mon Sep 17 00:00:00 2001 From: trekhleb Date: Sat, 9 Mar 2024 16:03:43 +0100 Subject: [PATCH 1/4] Add DisjointSetMinimalistic --- .../disjoint-set/DisjointSetMinimalistic.js | 77 +++++++++++++++++++ .../__test__/DisjointSetMinimalistic.test.js | 50 ++++++++++++ 2 files changed, 127 insertions(+) create mode 100644 src/data-structures/disjoint-set/DisjointSetMinimalistic.js create mode 100644 src/data-structures/disjoint-set/__test__/DisjointSetMinimalistic.test.js diff --git a/src/data-structures/disjoint-set/DisjointSetMinimalistic.js b/src/data-structures/disjoint-set/DisjointSetMinimalistic.js new file mode 100644 index 0000000000..dbc8067999 --- /dev/null +++ b/src/data-structures/disjoint-set/DisjointSetMinimalistic.js @@ -0,0 +1,77 @@ +/** + * The minimalistic version of a DisjointSet (or a UnionFind) data structure + * that doesn't have external dependencies and that is easy to copy-paste and + * use during the coding interview (since many data structures in JS are missing). + * + * Time Complexity: + * + * - Constructor: O(N) + * - Find: O(α(N)) + * - Union: O(α(N)) + * - Connected: O(α(N)) + * + * Where N is the number of vertices in the graph. + * α refers to the Inverse Ackermann function. + * In practice, we assume it's a constant. + * In other words, O(α(N)) is regarded as O(1) on average. + */ +class DisjointSetMinimalistic { + /** + * Initializes the set of specified size. + * @param {number} size + */ + constructor(size) { + // The index of a cell is an id of the node in a set. + // The value of a cell is an id (index) of the root node. + // By default, the node is a parent of itself. + this.roots = new Array(size).fill(0).map((_, i) => i); + + // Using the heights array to record the height of each node. + // By default each node has a height of 1 because it has no children. + this.heights = new Array(size).fill(1); + } + + /** + * Finds the root of node `a` + * @param {number} a + * @returns {number} + */ + find(a) { + if (a === this.roots[a]) return a; + this.roots[a] = this.find(this.roots[a]); + return this.roots[a]; + } + + /** + * Joins the `a` and `b` nodes into same set. + * @param {number} a + * @param {number} b + * @returns {number} + */ + union(a, b) { + const aRoot = this.find(a); + const bRoot = this.find(b); + + if (aRoot === bRoot) return; + + if (this.heights[aRoot] > this.heights[bRoot]) { + this.roots[bRoot] = aRoot; + } else if (this.heights[aRoot] < this.heights[bRoot]) { + this.roots[aRoot] = bRoot; + } else { + this.roots[bRoot] = aRoot; + this.heights[aRoot] += 1; + } + } + + /** + * Checks if `a` and `b` belong to the same set. + * @param {number} a + * @param {number} b + */ + connected(a, b) { + return this.find(a) === this.find(b); + } +} + +export default DisjointSetMinimalistic; diff --git a/src/data-structures/disjoint-set/__test__/DisjointSetMinimalistic.test.js b/src/data-structures/disjoint-set/__test__/DisjointSetMinimalistic.test.js new file mode 100644 index 0000000000..6ea3d0e7fe --- /dev/null +++ b/src/data-structures/disjoint-set/__test__/DisjointSetMinimalistic.test.js @@ -0,0 +1,50 @@ +import DisjointSetMinimalistic from '../DisjointSetMinimalistic'; + +describe('DisjointSetMinimalistic', () => { + it('should create unions and find connected elements', () => { + const set = new DisjointSetMinimalistic(10); + + // 1-2-5-6-7 3-8-9 4 + set.union(1, 2); + set.union(2, 5); + set.union(5, 6); + set.union(6, 7); + + set.union(3, 8); + set.union(8, 9); + + expect(set.connected(1, 5)).toBe(true); + expect(set.connected(5, 7)).toBe(true); + expect(set.connected(3, 8)).toBe(true); + + expect(set.connected(4, 9)).toBe(false); + expect(set.connected(4, 7)).toBe(false); + + // 1-2-5-6-7 3-8-9-4 + set.union(9, 4); + + expect(set.connected(4, 9)).toBe(true); + expect(set.connected(4, 3)).toBe(true); + expect(set.connected(8, 4)).toBe(true); + + expect(set.connected(8, 7)).toBe(false); + expect(set.connected(2, 3)).toBe(false); + }); + + it('should keep the height of the tree small', () => { + const set = new DisjointSetMinimalistic(10); + + // 1-2-6-7-9 1 3 4 5 + set.union(7, 6); + set.union(1, 2); + set.union(2, 6); + set.union(1, 7); + set.union(9, 1); + + expect(set.connected(1, 7)).toBe(true); + expect(set.connected(6, 9)).toBe(true); + expect(set.connected(4, 9)).toBe(false); + + expect(Math.max(...set.heights)).toBe(3); + }); +}); From 1260050c7653939f3f1273629e95bc5e7bee62d6 Mon Sep 17 00:00:00 2001 From: trekhleb Date: Sat, 9 Mar 2024 16:34:40 +0100 Subject: [PATCH 2/4] Add MinHeapMinimalistic and MaxHeapMinimalistic --- .../disjoint-set/DisjointSetMinimalistic.js | 3 +- .../heap/MaxHeapMinimalistic.js | 115 +++++++++++++++++ .../heap/MinHeapMinimalistic.js | 117 ++++++++++++++++++ .../heap/__test__/MaxHeapMinimalistic.test.js | 91 ++++++++++++++ .../heap/__test__/MinHeapMinimalistic.test.js | 91 ++++++++++++++ 5 files changed, 416 insertions(+), 1 deletion(-) create mode 100644 src/data-structures/heap/MaxHeapMinimalistic.js create mode 100644 src/data-structures/heap/MinHeapMinimalistic.js create mode 100644 src/data-structures/heap/__test__/MaxHeapMinimalistic.test.js create mode 100644 src/data-structures/heap/__test__/MinHeapMinimalistic.test.js diff --git a/src/data-structures/disjoint-set/DisjointSetMinimalistic.js b/src/data-structures/disjoint-set/DisjointSetMinimalistic.js index dbc8067999..1c9b37ac7e 100644 --- a/src/data-structures/disjoint-set/DisjointSetMinimalistic.js +++ b/src/data-structures/disjoint-set/DisjointSetMinimalistic.js @@ -1,7 +1,8 @@ /** * The minimalistic version of a DisjointSet (or a UnionFind) data structure * that doesn't have external dependencies and that is easy to copy-paste and - * use during the coding interview (since many data structures in JS are missing). + * use during the coding interview if allowed by the interviewer (since many + * data structures in JS are missing). * * Time Complexity: * diff --git a/src/data-structures/heap/MaxHeapMinimalistic.js b/src/data-structures/heap/MaxHeapMinimalistic.js new file mode 100644 index 0000000000..fb37425e70 --- /dev/null +++ b/src/data-structures/heap/MaxHeapMinimalistic.js @@ -0,0 +1,115 @@ +/** + * The minimalistic version of a MaxHeap data structure that doesn't have + * external dependencies and that is easy to copy-paste and use during the + * coding interview if allowed by the interviewer (since many data + * structures in JS are missing). + */ +class MaxHeapMinimalistic { + constructor(heap = []) { + this.heap = []; + heap.forEach(this.add); + } + + add(num) { + this.heap.push(num); + this.heapifyUp(); + } + + peek() { + return this.heap[0]; + } + + poll() { + if (this.heap.length === 0) return undefined; + const top = this.heap[0]; + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap.pop(); + this.heapifyDown(); + return top; + } + + isEmpty() { + return this.heap.length === 0; + } + + toString() { + return this.heap.join(','); + } + + heapifyUp() { + let nodeIndex = this.heap.length - 1; + while (nodeIndex > 0) { + const parentIndex = this.getParentIndex(nodeIndex); + if (this.heap[parentIndex] >= this.heap[nodeIndex]) break; + this.swap(parentIndex, nodeIndex); + nodeIndex = parentIndex; + } + } + + heapifyDown() { + let nodeIndex = 0; + + while ( + ( + this.hasLeftChild(nodeIndex) && this.heap[nodeIndex] < this.leftChild(nodeIndex) + ) + || ( + this.hasRightChild(nodeIndex) && this.heap[nodeIndex] < this.rightChild(nodeIndex) + ) + ) { + const leftIndex = this.getLeftChildIndex(nodeIndex); + const rightIndex = this.getRightChildIndex(nodeIndex); + const left = this.leftChild(nodeIndex); + const right = this.rightChild(nodeIndex); + + if (this.hasLeftChild(nodeIndex) && this.hasRightChild(nodeIndex)) { + if (left >= right) { + this.swap(leftIndex, nodeIndex); + nodeIndex = leftIndex; + } else { + this.swap(rightIndex, nodeIndex); + nodeIndex = rightIndex; + } + } else if (this.hasLeftChild(nodeIndex)) { + this.swap(leftIndex, nodeIndex); + nodeIndex = leftIndex; + } + } + } + + getLeftChildIndex(parentIndex) { + return (2 * parentIndex) + 1; + } + + getRightChildIndex(parentIndex) { + return (2 * parentIndex) + 2; + } + + getParentIndex(childIndex) { + return Math.floor((childIndex - 1) / 2); + } + + hasLeftChild(parentIndex) { + return this.getLeftChildIndex(parentIndex) < this.heap.length; + } + + hasRightChild(parentIndex) { + return this.getRightChildIndex(parentIndex) < this.heap.length; + } + + leftChild(parentIndex) { + return this.heap[this.getLeftChildIndex(parentIndex)]; + } + + rightChild(parentIndex) { + return this.heap[this.getRightChildIndex(parentIndex)]; + } + + swap(indexOne, indexTwo) { + const tmp = this.heap[indexTwo]; + this.heap[indexTwo] = this.heap[indexOne]; + this.heap[indexOne] = tmp; + } +} + +export default MaxHeapMinimalistic; diff --git a/src/data-structures/heap/MinHeapMinimalistic.js b/src/data-structures/heap/MinHeapMinimalistic.js new file mode 100644 index 0000000000..e31c445f5b --- /dev/null +++ b/src/data-structures/heap/MinHeapMinimalistic.js @@ -0,0 +1,117 @@ +/** + * The minimalistic version of a MinHeap data structure that doesn't have + * external dependencies and that is easy to copy-paste and use during the + * coding interview if allowed by the interviewer (since many data + * structures in JS are missing). + */ +class MinHeapMinimalistic { + constructor(heap = []) { + this.heap = []; + heap.forEach(this.add); + } + + add(num) { + this.heap.push(num); + this.heapifyUp(); + } + + peek() { + return this.heap[0]; + } + + poll() { + if (this.heap.length === 0) return undefined; + const top = this.heap[0]; + this.heap[0] = this.heap[this.heap.length - 1]; + this.heap.pop(); + this.heapifyDown(); + return top; + } + + isEmpty() { + return this.heap.length === 0; + } + + toString() { + return this.heap.join(','); + } + + heapifyUp() { + let nodeIndex = this.heap.length - 1; + while (nodeIndex > 0) { + const parentIndex = this.getParentIndex(nodeIndex); + if (this.heap[parentIndex] <= this.heap[nodeIndex]) break; + this.swap(parentIndex, nodeIndex); + nodeIndex = parentIndex; + } + } + + heapifyDown() { + let nodeIndex = 0; + + while ( + ( + this.hasLeftChild(nodeIndex) + && this.heap[nodeIndex] > this.leftChild(nodeIndex) + ) + || ( + this.hasRightChild(nodeIndex) + && this.heap[nodeIndex] > this.rightChild(nodeIndex) + ) + ) { + const leftIndex = this.getLeftChildIndex(nodeIndex); + const rightIndex = this.getRightChildIndex(nodeIndex); + const left = this.leftChild(nodeIndex); + const right = this.rightChild(nodeIndex); + + if (this.hasLeftChild(nodeIndex) && this.hasRightChild(nodeIndex)) { + if (left <= right) { + this.swap(leftIndex, nodeIndex); + nodeIndex = leftIndex; + } else { + this.swap(rightIndex, nodeIndex); + nodeIndex = rightIndex; + } + } else if (this.hasLeftChild(nodeIndex)) { + this.swap(leftIndex, nodeIndex); + nodeIndex = leftIndex; + } + } + } + + getLeftChildIndex(parentIndex) { + return 2 * parentIndex + 1; + } + + getRightChildIndex(parentIndex) { + return 2 * parentIndex + 2; + } + + getParentIndex(childIndex) { + return Math.floor((childIndex - 1) / 2); + } + + hasLeftChild(parentIndex) { + return this.getLeftChildIndex(parentIndex) < this.heap.length; + } + + hasRightChild(parentIndex) { + return this.getRightChildIndex(parentIndex) < this.heap.length; + } + + leftChild(parentIndex) { + return this.heap[this.getLeftChildIndex(parentIndex)]; + } + + rightChild(parentIndex) { + return this.heap[this.getRightChildIndex(parentIndex)]; + } + + swap(indexOne, indexTwo) { + const tmp = this.heap[indexTwo]; + this.heap[indexTwo] = this.heap[indexOne]; + this.heap[indexOne] = tmp; + } +} + +export default MinHeapMinimalistic; diff --git a/src/data-structures/heap/__test__/MaxHeapMinimalistic.test.js b/src/data-structures/heap/__test__/MaxHeapMinimalistic.test.js new file mode 100644 index 0000000000..ab6f2a0123 --- /dev/null +++ b/src/data-structures/heap/__test__/MaxHeapMinimalistic.test.js @@ -0,0 +1,91 @@ +import MaxHeap from '../MaxHeapMinimalistic'; + +describe('MaxHeap', () => { + it('should create an empty max heap', () => { + const maxHeap = new MaxHeap(); + + expect(maxHeap).toBeDefined(); + expect(maxHeap.peek()).toBe(undefined); + expect(maxHeap.isEmpty()).toBe(true); + }); + + it('should add items to the heap and heapify it up', () => { + const maxHeap = new MaxHeap(); + + maxHeap.add(5); + expect(maxHeap.isEmpty()).toBe(false); + expect(maxHeap.peek()).toBe(5); + expect(maxHeap.toString()).toBe('5'); + + maxHeap.add(3); + expect(maxHeap.peek()).toBe(5); + expect(maxHeap.toString()).toBe('5,3'); + + maxHeap.add(10); + expect(maxHeap.peek()).toBe(10); + expect(maxHeap.toString()).toBe('10,3,5'); + + maxHeap.add(1); + expect(maxHeap.peek()).toBe(10); + expect(maxHeap.toString()).toBe('10,3,5,1'); + + maxHeap.add(1); + expect(maxHeap.peek()).toBe(10); + expect(maxHeap.toString()).toBe('10,3,5,1,1'); + + expect(maxHeap.poll()).toBe(10); + expect(maxHeap.toString()).toBe('5,3,1,1'); + + expect(maxHeap.poll()).toBe(5); + expect(maxHeap.toString()).toBe('3,1,1'); + + expect(maxHeap.poll()).toBe(3); + expect(maxHeap.toString()).toBe('1,1'); + }); + + it('should poll items from the heap and heapify it down', () => { + const maxHeap = new MaxHeap(); + + maxHeap.add(5); + maxHeap.add(3); + maxHeap.add(10); + maxHeap.add(11); + maxHeap.add(1); + + expect(maxHeap.toString()).toBe('11,10,5,3,1'); + + expect(maxHeap.poll()).toBe(11); + expect(maxHeap.toString()).toBe('10,3,5,1'); + + expect(maxHeap.poll()).toBe(10); + expect(maxHeap.toString()).toBe('5,3,1'); + + expect(maxHeap.poll()).toBe(5); + expect(maxHeap.toString()).toBe('3,1'); + + expect(maxHeap.poll()).toBe(3); + expect(maxHeap.toString()).toBe('1'); + + expect(maxHeap.poll()).toBe(1); + expect(maxHeap.toString()).toBe(''); + + expect(maxHeap.poll()).toBe(undefined); + expect(maxHeap.toString()).toBe(''); + }); + + it('should heapify down through the right branch as well', () => { + const maxHeap = new MaxHeap(); + + maxHeap.add(3); + maxHeap.add(12); + maxHeap.add(10); + + expect(maxHeap.toString()).toBe('12,3,10'); + + maxHeap.add(11); + expect(maxHeap.toString()).toBe('12,11,10,3'); + + expect(maxHeap.poll()).toBe(12); + expect(maxHeap.toString()).toBe('11,3,10'); + }); +}); diff --git a/src/data-structures/heap/__test__/MinHeapMinimalistic.test.js b/src/data-structures/heap/__test__/MinHeapMinimalistic.test.js new file mode 100644 index 0000000000..46aecc8065 --- /dev/null +++ b/src/data-structures/heap/__test__/MinHeapMinimalistic.test.js @@ -0,0 +1,91 @@ +import MinHeapMinimalistic from '../MinHeapMinimalistic'; + +describe('MinHeapMinimalistic', () => { + it('should create an empty min heap', () => { + const minHeap = new MinHeapMinimalistic(); + + expect(minHeap).toBeDefined(); + expect(minHeap.peek()).toBe(undefined); + expect(minHeap.isEmpty()).toBe(true); + }); + + it('should add items to the heap and heapify it up', () => { + const minHeap = new MinHeapMinimalistic(); + + minHeap.add(5); + expect(minHeap.isEmpty()).toBe(false); + expect(minHeap.peek()).toBe(5); + expect(minHeap.toString()).toBe('5'); + + minHeap.add(3); + expect(minHeap.peek()).toBe(3); + expect(minHeap.toString()).toBe('3,5'); + + minHeap.add(10); + expect(minHeap.peek()).toBe(3); + expect(minHeap.toString()).toBe('3,5,10'); + + minHeap.add(1); + expect(minHeap.peek()).toBe(1); + expect(minHeap.toString()).toBe('1,3,10,5'); + + minHeap.add(1); + expect(minHeap.peek()).toBe(1); + expect(minHeap.toString()).toBe('1,1,10,5,3'); + + expect(minHeap.poll()).toBe(1); + expect(minHeap.toString()).toBe('1,3,10,5'); + + expect(minHeap.poll()).toBe(1); + expect(minHeap.toString()).toBe('3,5,10'); + + expect(minHeap.poll()).toBe(3); + expect(minHeap.toString()).toBe('5,10'); + }); + + it('should poll items from the heap and heapify it down', () => { + const minHeap = new MinHeapMinimalistic(); + + minHeap.add(5); + minHeap.add(3); + minHeap.add(10); + minHeap.add(11); + minHeap.add(1); + + expect(minHeap.toString()).toBe('1,3,10,11,5'); + + expect(minHeap.poll()).toBe(1); + expect(minHeap.toString()).toBe('3,5,10,11'); + + expect(minHeap.poll()).toBe(3); + expect(minHeap.toString()).toBe('5,11,10'); + + expect(minHeap.poll()).toBe(5); + expect(minHeap.toString()).toBe('10,11'); + + expect(minHeap.poll()).toBe(10); + expect(minHeap.toString()).toBe('11'); + + expect(minHeap.poll()).toBe(11); + expect(minHeap.toString()).toBe(''); + + expect(minHeap.poll()).toBe(undefined); + expect(minHeap.toString()).toBe(''); + }); + + it('should heapify down through the right branch as well', () => { + const minHeap = new MinHeapMinimalistic(); + + minHeap.add(3); + minHeap.add(12); + minHeap.add(10); + + expect(minHeap.toString()).toBe('3,12,10'); + + minHeap.add(11); + expect(minHeap.toString()).toBe('3,11,10,12'); + + expect(minHeap.poll()).toBe(3); + expect(minHeap.toString()).toBe('10,11,12'); + }); +}); From 455093cfd2919ea1a64919be4099507ac4beba42 Mon Sep 17 00:00:00 2001 From: trekhleb Date: Sat, 9 Mar 2024 16:40:06 +0100 Subject: [PATCH 3/4] Rename minimalistic to adhoc --- ...isjointSetMinimalistic.js => DisjointSetAdhoc.js} | 6 +++--- ...Minimalistic.test.js => DisjointSetAdhoc.test.js} | 8 ++++---- .../heap/{MaxHeapMinimalistic.js => MaxHeapAdhoc.js} | 6 +++--- .../heap/{MinHeapMinimalistic.js => MinHeapAdhoc.js} | 6 +++--- ...HeapMinimalistic.test.js => MaxHeapAdhoc.test.js} | 4 ++-- ...HeapMinimalistic.test.js => MinHeapAdhoc.test.js} | 12 ++++++------ 6 files changed, 21 insertions(+), 21 deletions(-) rename src/data-structures/disjoint-set/{DisjointSetMinimalistic.js => DisjointSetAdhoc.js} (92%) rename src/data-structures/disjoint-set/__test__/{DisjointSetMinimalistic.test.js => DisjointSetAdhoc.test.js} (84%) rename src/data-structures/heap/{MaxHeapMinimalistic.js => MaxHeapAdhoc.js} (95%) rename src/data-structures/heap/{MinHeapMinimalistic.js => MinHeapAdhoc.js} (95%) rename src/data-structures/heap/__test__/{MaxHeapMinimalistic.test.js => MaxHeapAdhoc.test.js} (96%) rename src/data-structures/heap/__test__/{MinHeapMinimalistic.test.js => MinHeapAdhoc.test.js} (88%) diff --git a/src/data-structures/disjoint-set/DisjointSetMinimalistic.js b/src/data-structures/disjoint-set/DisjointSetAdhoc.js similarity index 92% rename from src/data-structures/disjoint-set/DisjointSetMinimalistic.js rename to src/data-structures/disjoint-set/DisjointSetAdhoc.js index 1c9b37ac7e..9653418042 100644 --- a/src/data-structures/disjoint-set/DisjointSetMinimalistic.js +++ b/src/data-structures/disjoint-set/DisjointSetAdhoc.js @@ -1,5 +1,5 @@ /** - * The minimalistic version of a DisjointSet (or a UnionFind) data structure + * The minimalistic (ad hoc) version of a DisjointSet (or a UnionFind) data structure * that doesn't have external dependencies and that is easy to copy-paste and * use during the coding interview if allowed by the interviewer (since many * data structures in JS are missing). @@ -16,7 +16,7 @@ * In practice, we assume it's a constant. * In other words, O(α(N)) is regarded as O(1) on average. */ -class DisjointSetMinimalistic { +class DisjointSetAdhoc { /** * Initializes the set of specified size. * @param {number} size @@ -75,4 +75,4 @@ class DisjointSetMinimalistic { } } -export default DisjointSetMinimalistic; +export default DisjointSetAdhoc; diff --git a/src/data-structures/disjoint-set/__test__/DisjointSetMinimalistic.test.js b/src/data-structures/disjoint-set/__test__/DisjointSetAdhoc.test.js similarity index 84% rename from src/data-structures/disjoint-set/__test__/DisjointSetMinimalistic.test.js rename to src/data-structures/disjoint-set/__test__/DisjointSetAdhoc.test.js index 6ea3d0e7fe..f7be0fcde9 100644 --- a/src/data-structures/disjoint-set/__test__/DisjointSetMinimalistic.test.js +++ b/src/data-structures/disjoint-set/__test__/DisjointSetAdhoc.test.js @@ -1,8 +1,8 @@ -import DisjointSetMinimalistic from '../DisjointSetMinimalistic'; +import DisjointSetAdhoc from '../DisjointSetAdhoc'; -describe('DisjointSetMinimalistic', () => { +describe('DisjointSetAdhoc', () => { it('should create unions and find connected elements', () => { - const set = new DisjointSetMinimalistic(10); + const set = new DisjointSetAdhoc(10); // 1-2-5-6-7 3-8-9 4 set.union(1, 2); @@ -32,7 +32,7 @@ describe('DisjointSetMinimalistic', () => { }); it('should keep the height of the tree small', () => { - const set = new DisjointSetMinimalistic(10); + const set = new DisjointSetAdhoc(10); // 1-2-6-7-9 1 3 4 5 set.union(7, 6); diff --git a/src/data-structures/heap/MaxHeapMinimalistic.js b/src/data-structures/heap/MaxHeapAdhoc.js similarity index 95% rename from src/data-structures/heap/MaxHeapMinimalistic.js rename to src/data-structures/heap/MaxHeapAdhoc.js index fb37425e70..b9d69c59e0 100644 --- a/src/data-structures/heap/MaxHeapMinimalistic.js +++ b/src/data-structures/heap/MaxHeapAdhoc.js @@ -1,10 +1,10 @@ /** - * The minimalistic version of a MaxHeap data structure that doesn't have + * The minimalistic (ad hoc) version of a MaxHeap data structure that doesn't have * external dependencies and that is easy to copy-paste and use during the * coding interview if allowed by the interviewer (since many data * structures in JS are missing). */ -class MaxHeapMinimalistic { +class MaxHeapAdhoc { constructor(heap = []) { this.heap = []; heap.forEach(this.add); @@ -112,4 +112,4 @@ class MaxHeapMinimalistic { } } -export default MaxHeapMinimalistic; +export default MaxHeapAdhoc; diff --git a/src/data-structures/heap/MinHeapMinimalistic.js b/src/data-structures/heap/MinHeapAdhoc.js similarity index 95% rename from src/data-structures/heap/MinHeapMinimalistic.js rename to src/data-structures/heap/MinHeapAdhoc.js index e31c445f5b..c70692f3de 100644 --- a/src/data-structures/heap/MinHeapMinimalistic.js +++ b/src/data-structures/heap/MinHeapAdhoc.js @@ -1,10 +1,10 @@ /** - * The minimalistic version of a MinHeap data structure that doesn't have + * The minimalistic (ad hoc) version of a MinHeap data structure that doesn't have * external dependencies and that is easy to copy-paste and use during the * coding interview if allowed by the interviewer (since many data * structures in JS are missing). */ -class MinHeapMinimalistic { +class MinHeapAdhoc { constructor(heap = []) { this.heap = []; heap.forEach(this.add); @@ -114,4 +114,4 @@ class MinHeapMinimalistic { } } -export default MinHeapMinimalistic; +export default MinHeapAdhoc; diff --git a/src/data-structures/heap/__test__/MaxHeapMinimalistic.test.js b/src/data-structures/heap/__test__/MaxHeapAdhoc.test.js similarity index 96% rename from src/data-structures/heap/__test__/MaxHeapMinimalistic.test.js rename to src/data-structures/heap/__test__/MaxHeapAdhoc.test.js index ab6f2a0123..0217a98ddf 100644 --- a/src/data-structures/heap/__test__/MaxHeapMinimalistic.test.js +++ b/src/data-structures/heap/__test__/MaxHeapAdhoc.test.js @@ -1,6 +1,6 @@ -import MaxHeap from '../MaxHeapMinimalistic'; +import MaxHeap from '../MaxHeapAdhoc'; -describe('MaxHeap', () => { +describe('MaxHeapAdhoc', () => { it('should create an empty max heap', () => { const maxHeap = new MaxHeap(); diff --git a/src/data-structures/heap/__test__/MinHeapMinimalistic.test.js b/src/data-structures/heap/__test__/MinHeapAdhoc.test.js similarity index 88% rename from src/data-structures/heap/__test__/MinHeapMinimalistic.test.js rename to src/data-structures/heap/__test__/MinHeapAdhoc.test.js index 46aecc8065..766b307ff0 100644 --- a/src/data-structures/heap/__test__/MinHeapMinimalistic.test.js +++ b/src/data-structures/heap/__test__/MinHeapAdhoc.test.js @@ -1,8 +1,8 @@ -import MinHeapMinimalistic from '../MinHeapMinimalistic'; +import MinHeapAdhoc from '../MinHeapAdhoc'; -describe('MinHeapMinimalistic', () => { +describe('MinHeapAdhoc', () => { it('should create an empty min heap', () => { - const minHeap = new MinHeapMinimalistic(); + const minHeap = new MinHeapAdhoc(); expect(minHeap).toBeDefined(); expect(minHeap.peek()).toBe(undefined); @@ -10,7 +10,7 @@ describe('MinHeapMinimalistic', () => { }); it('should add items to the heap and heapify it up', () => { - const minHeap = new MinHeapMinimalistic(); + const minHeap = new MinHeapAdhoc(); minHeap.add(5); expect(minHeap.isEmpty()).toBe(false); @@ -44,7 +44,7 @@ describe('MinHeapMinimalistic', () => { }); it('should poll items from the heap and heapify it down', () => { - const minHeap = new MinHeapMinimalistic(); + const minHeap = new MinHeapAdhoc(); minHeap.add(5); minHeap.add(3); @@ -74,7 +74,7 @@ describe('MinHeapMinimalistic', () => { }); it('should heapify down through the right branch as well', () => { - const minHeap = new MinHeapMinimalistic(); + const minHeap = new MinHeapAdhoc(); minHeap.add(3); minHeap.add(12); From 36a2796345992b546775fb198b7e52d32cd7a159 Mon Sep 17 00:00:00 2001 From: trekhleb Date: Sat, 9 Mar 2024 16:48:39 +0100 Subject: [PATCH 4/4] Update README --- src/data-structures/disjoint-set/README.md | 5 +++++ src/data-structures/heap/README.md | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/data-structures/disjoint-set/README.md b/src/data-structures/disjoint-set/README.md index 44bcfa2769..772f68191b 100644 --- a/src/data-structures/disjoint-set/README.md +++ b/src/data-structures/disjoint-set/README.md @@ -19,6 +19,11 @@ _MakeSet_ creates 8 singletons. After some operations of _Union_, some sets are grouped together. +## Implementation + +- [DisjointSet.js](./DisjointSet.js) +- [DisjointSetAdhoc.js](./DisjointSetAdhoc.js) - The minimalistic (ad hoc) version of a DisjointSet (or a UnionFind) data structure that doesn't have external dependencies and that is easy to copy-paste and use during the coding interview if allowed by the interviewer (since many data structures in JS are missing). + ## References - [Wikipedia](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) diff --git a/src/data-structures/heap/README.md b/src/data-structures/heap/README.md index 824d646043..392c5c96bc 100644 --- a/src/data-structures/heap/README.md +++ b/src/data-structures/heap/README.md @@ -58,6 +58,11 @@ Where: > In this repository, the [MaxHeap.js](./MaxHeap.js) and [MinHeap.js](./MinHeap.js) are examples of the **Binary** heap. +## Implementation + +- [MaxHeap.js](./MaxHeap.js) and [MinHeap.js](./MinHeap.js) +- [MaxHeapAdhoc.js](./MaxHeapAdhoc.js) and [MinHeapAdhoc.js](./MinHeapAdhoc.js) - The minimalistic (ad hoc) version of a MinHeap/MaxHeap data structure that doesn't have external dependencies and that is easy to copy-paste and use during the coding interview if allowed by the interviewer (since many data structures in JS are missing). + ## References - [Wikipedia](https://en.wikipedia.org/wiki/Heap_(data_structure))