
* Fix LinkedList * Fix the prepend method for the LinkedList * Fix the remove method for the MinHeap * Correct a comment * Fix BST removal method * Fix the findEdge method of the graph * Fix the value returned by DisjointSet union
98 lines
2.2 KiB
JavaScript
98 lines
2.2 KiB
JavaScript
import DisjointSetItem from './DisjointSetItem';
|
|
|
|
export default class DisjointSet {
|
|
/**
|
|
* @param {function(value: *)} [keyCallback]
|
|
*/
|
|
constructor(keyCallback) {
|
|
this.keyCallback = keyCallback;
|
|
this.items = {};
|
|
}
|
|
|
|
/**
|
|
* @param {*} itemValue
|
|
* @return {DisjointSet}
|
|
*/
|
|
makeSet(itemValue) {
|
|
const disjointSetItem = new DisjointSetItem(itemValue, this.keyCallback);
|
|
|
|
if (!this.items[disjointSetItem.getKey()]) {
|
|
// Add new item only in case if it not presented yet.
|
|
this.items[disjointSetItem.getKey()] = disjointSetItem;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Find set representation node.
|
|
*
|
|
* @param {*} itemValue
|
|
* @return {(string|null)}
|
|
*/
|
|
find(itemValue) {
|
|
const templateDisjointItem = new DisjointSetItem(itemValue, this.keyCallback);
|
|
|
|
// Try to find item itself;
|
|
const requiredDisjointItem = this.items[templateDisjointItem.getKey()];
|
|
|
|
if (!requiredDisjointItem) {
|
|
return null;
|
|
}
|
|
|
|
return requiredDisjointItem.getRoot().getKey();
|
|
}
|
|
|
|
/**
|
|
* Union by rank.
|
|
*
|
|
* @param {*} valueA
|
|
* @param {*} valueB
|
|
* @return {DisjointSet}
|
|
*/
|
|
union(valueA, valueB) {
|
|
const rootKeyA = this.find(valueA);
|
|
const rootKeyB = this.find(valueB);
|
|
|
|
if (rootKeyA === null || rootKeyB === null) {
|
|
throw new Error('One or two values are not in sets');
|
|
}
|
|
|
|
if (rootKeyA === rootKeyB) {
|
|
// In case if both elements are already in the same set then just return its key.
|
|
return this;
|
|
}
|
|
|
|
const rootA = this.items[rootKeyA];
|
|
const rootB = this.items[rootKeyB];
|
|
|
|
if (rootA.getRank() < rootB.getRank()) {
|
|
// If rootB's tree is bigger then make rootB to be a new root.
|
|
rootB.addChild(rootA);
|
|
|
|
return this;
|
|
}
|
|
|
|
// If rootA's tree is bigger then make rootA to be a new root.
|
|
rootA.addChild(rootB);
|
|
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* @param {*} valueA
|
|
* @param {*} valueB
|
|
* @return {boolean}
|
|
*/
|
|
inSameSet(valueA, valueB) {
|
|
const rootKeyA = this.find(valueA);
|
|
const rootKeyB = this.find(valueB);
|
|
|
|
if (rootKeyA === null || rootKeyB === null) {
|
|
throw new Error('One or two values are not in sets');
|
|
}
|
|
|
|
return rootKeyA === rootKeyB;
|
|
}
|
|
}
|