diff --git a/Data-Structures/Disjoint-Set/UnionByRank.js b/Data-Structures/Disjoint-Set/UnionByRank.js new file mode 100644 index 0000000000..b5f63e9cd1 --- /dev/null +++ b/Data-Structures/Disjoint-Set/UnionByRank.js @@ -0,0 +1,62 @@ +// Data Structure - DISJOINT SET +// Use-case - Used to find two nodes are in same component or not + +// Time complexity +// constructor - O(n) +// find_parent - O(1) +// union_by_rank- O(1) + +// Space Complexity: O(n) + +class DSU { + parent = [] + rank = [] + + constructor(number_of_node) { + this.parent = [...this.parent, ...Array(number_of_node).fill(0)] + this.rank = [...this.rank, ...Array(number_of_node).fill(0)] + + // initially all nodes are parent of itself + // initially there are (number_of _node) components + for (let i = 0; i < number_of_node; i++) { + this.parent[i] = i + } + } + + find_parent(node) { + // if current node is parent of itself + if (node == this.parent[node]) return node + + // Path Compression for finding the ultimate parent efficiently + return (this.parent[node] = this.find_parent(this.parent[node])) + } + + union_by_rank(node_1, node_2) { + let node_1_parent = this.find_parent(node_1) + let node_2_parent = this.find_parent(node_2) + + // if two nodes are already in same component + if (node_1_parent === node_2_parent) return + // if node_1_parent has more rank than node_2_parent + else if (this.rank[node_1_parent]> this.rank[node_2_parent]) { + // merging component 2 into component 1 + this.parent[node_2_parent] = node_1_parent + } + + // if node_2_parent has more rank than node_1_parent + else if (this.rank[node_2_parent]> this.rank[node_1_parent]) { + // merging component 1 into component 2 + this.parent[node_1_parent] = node_2_parent + } + + // if node_1_parent and node_2_parent has equal rank + else { + // we can merge any one component to other component because both have same rank + // we are merging component 1 into component 2 + this.parent[node_1_parent] = node_2_parent + this.rank[node_2_parent]++ + } + } +} + +export default DSU diff --git a/Data-Structures/Disjoint-Set/UnionBySize.js b/Data-Structures/Disjoint-Set/UnionBySize.js new file mode 100644 index 0000000000..ff0f5b469b --- /dev/null +++ b/Data-Structures/Disjoint-Set/UnionBySize.js @@ -0,0 +1,61 @@ +// Data Structure - DISJOINT SET +// Use-case - Used to find two nodes are in same component or not + +// Time complexity +// constructor - O(n) +// find_parent - O(1) +// union_by_size- O(1) + +// Space Complexity: O(n) + +class DSU { + parent = [] + size = [] + + constructor(number_of_node) { + this.parent = [...this.parent, ...Array(number_of_node).fill(0)] + // initially all components have single node itself + this.size = [...this.size, ...Array(number_of_node).fill(1)] + + // initially all nodes are parent of itself + // initially there are (number_of _node) components + for (let i = 0; i < number_of_node; i++) { + this.parent[i] = i + } + } + + find_parent(node) { + // if current node is parent of itself + if (node == this.parent[node]) return node + + // Path Compression for finding the ultimate parent efficiently + return (this.parent[node] = this.find_parent(this.parent[node])) + } + + union_by_size(node_1, node_2) { + let node_1_parent = this.find_parent(node_1) + let node_2_parent = this.find_parent(node_2) + + // if two nodes are already in same component + if (node_1_parent === node_2_parent) return + // if node_1_parent has more size than node_2_parent + else if (this.size[node_1_parent]> this.size[node_2_parent]) { + // merging component 2 into component 1 + this.parent[node_2_parent] = node_1_parent + this.size[node_1_parent] += this.size[node_2_parent] + } + + // if node_2_parent has more or equal size than node_1_parent + else { + this.parent[node_1_parent] = node_2_parent + this.size[node_2_parent] += this.size[node_1_parent] + } + } + + find_size(node) { + let parent = this.find_parent(node) + return this.size[parent] + } +} + +export default DSU diff --git a/Data-Structures/Disjoint-Set/test/UnionByRank.test.js b/Data-Structures/Disjoint-Set/test/UnionByRank.test.js new file mode 100644 index 0000000000..aac4f5c881 --- /dev/null +++ b/Data-Structures/Disjoint-Set/test/UnionByRank.test.js @@ -0,0 +1,21 @@ +import { expect, test } from 'vitest' +import DSU from '../UnionByRank.js' +import { describe } from 'node:test' + +describe('union_by_rank', () => { + const dsu = new DSU(5) + + dsu.union_by_rank(0, 2) + dsu.union_by_rank(4, 2) + dsu.union_by_rank(3, 1) + + test('find parent of a particular node', () => { + expect(dsu.find_parent(0)).toBe(2) + expect(dsu.find_parent(4)).toBe(2) + }) + + test('finding if two nodes are in same component or not', () => { + expect(dsu.find_parent(4) == dsu.find_parent(0)).toBeTruthy() + expect(dsu.find_parent(3) == dsu.find_parent(2)).toBeFalsy() + }) +}) diff --git a/Data-Structures/Disjoint-Set/test/UnionBySize.test.js b/Data-Structures/Disjoint-Set/test/UnionBySize.test.js new file mode 100644 index 0000000000..adac4b4d24 --- /dev/null +++ b/Data-Structures/Disjoint-Set/test/UnionBySize.test.js @@ -0,0 +1,29 @@ +import { describe } from 'node:test' +import { expect, test } from 'vitest' +import DSU from '../UnionBySize' + +describe('union_by_size', () => { + const dsu = new DSU(5) + + dsu.union_by_size(0, 2) + dsu.union_by_size(4, 2) + dsu.union_by_size(3, 1) + + test('find parent of a particular node', () => { + expect(dsu.find_parent(0)).toBe(2) + expect(dsu.find_parent(4)).toBe(2) + }) + + test('finding if two nodes are in same component or not', () => { + expect(dsu.find_parent(4) == dsu.find_parent(0)).toBeTruthy() + expect(dsu.find_parent(3) == dsu.find_parent(2)).toBeFalsy() + }) + + test('finding size of a component', () => { + expect(dsu.find_size(3)).toBe(2) + + // all nodes unnited in single component + dsu.union_by_size(3, 0) + expect(dsu.find_size(3)).toBe(5) + }) +}) diff --git a/Maths/test/EuclideanDistance.test.js b/Maths/test/EuclideanDistance.test.js index d73bb03875..717ea2e6a0 100644 --- a/Maths/test/EuclideanDistance.test.js +++ b/Maths/test/EuclideanDistance.test.js @@ -2,11 +2,17 @@ import { EuclideanDistance } from '../EuclideanDistance.js' describe('EuclideanDistance', () => { it('should calculate the distance correctly for 2D vectors', () => { - expect(EuclideanDistance([0, 0], [2, 2])).toBeCloseTo(2.8284271247461903, 10) + expect(EuclideanDistance([0, 0], [2, 2])).toBeCloseTo( + 2.8284271247461903, + 10 + ) }) it('should calculate the distance correctly for 3D vectors', () => { - expect(EuclideanDistance([0, 0, 0], [2, 2, 2])).toBeCloseTo(3.4641016151377544, 10) + expect(EuclideanDistance([0, 0, 0], [2, 2, 2])).toBeCloseTo( + 3.4641016151377544, + 10 + ) }) it('should calculate the distance correctly for 4D vectors', () => {

AltStyle によって変換されたページ (->オリジナル) /