Projektstart
This commit is contained in:
195
backend/node_modules/mnemonist/static-disjoint-set.js
generated
vendored
Normal file
195
backend/node_modules/mnemonist/static-disjoint-set.js
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
/* eslint no-constant-condition: 0 */
|
||||
/**
|
||||
* Mnemonist StaticDisjointSet
|
||||
* ============================
|
||||
*
|
||||
* JavaScript implementation of a static disjoint set (union-find).
|
||||
*
|
||||
* Note that to remain performant, this implementation needs to know a size
|
||||
* beforehand.
|
||||
*/
|
||||
var helpers = require('./utils/typed-arrays.js');
|
||||
|
||||
/**
|
||||
* StaticDisjointSet.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function StaticDisjointSet(size) {
|
||||
|
||||
// Optimizing the typed array types
|
||||
var ParentsTypedArray = helpers.getPointerArray(size),
|
||||
RanksTypedArray = helpers.getPointerArray(Math.log2(size));
|
||||
|
||||
// Properties
|
||||
this.size = size;
|
||||
this.dimension = size;
|
||||
this.parents = new ParentsTypedArray(size);
|
||||
this.ranks = new RanksTypedArray(size);
|
||||
|
||||
// Initializing parents
|
||||
for (var i = 0; i < size; i++)
|
||||
this.parents[i] = i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method used to find the root of the given item.
|
||||
*
|
||||
* @param {number} x - Target item.
|
||||
* @return {number}
|
||||
*/
|
||||
StaticDisjointSet.prototype.find = function(x) {
|
||||
var y = x;
|
||||
|
||||
var c, p;
|
||||
|
||||
while (true) {
|
||||
c = this.parents[y];
|
||||
|
||||
if (y === c)
|
||||
break;
|
||||
|
||||
y = c;
|
||||
}
|
||||
|
||||
// Path compression
|
||||
while (true) {
|
||||
p = this.parents[x];
|
||||
|
||||
if (p === y)
|
||||
break;
|
||||
|
||||
this.parents[x] = y;
|
||||
x = p;
|
||||
}
|
||||
|
||||
return y;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method used to perform the union of two items.
|
||||
*
|
||||
* @param {number} x - First item.
|
||||
* @param {number} y - Second item.
|
||||
* @return {StaticDisjointSet}
|
||||
*/
|
||||
StaticDisjointSet.prototype.union = function(x, y) {
|
||||
var xRoot = this.find(x),
|
||||
yRoot = this.find(y);
|
||||
|
||||
// x and y are already in the same set
|
||||
if (xRoot === yRoot)
|
||||
return this;
|
||||
|
||||
this.dimension--;
|
||||
|
||||
// x and y are not in the same set, we merge them
|
||||
var xRank = this.ranks[x],
|
||||
yRank = this.ranks[y];
|
||||
|
||||
if (xRank < yRank) {
|
||||
this.parents[xRoot] = yRoot;
|
||||
}
|
||||
else if (xRank > yRank) {
|
||||
this.parents[yRoot] = xRoot;
|
||||
}
|
||||
else {
|
||||
this.parents[yRoot] = xRoot;
|
||||
this.ranks[xRoot]++;
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method returning whether two items are connected.
|
||||
*
|
||||
* @param {number} x - First item.
|
||||
* @param {number} y - Second item.
|
||||
* @return {boolean}
|
||||
*/
|
||||
StaticDisjointSet.prototype.connected = function(x, y) {
|
||||
var xRoot = this.find(x);
|
||||
|
||||
return xRoot === this.find(y);
|
||||
};
|
||||
|
||||
/**
|
||||
* Method returning the set mapping.
|
||||
*
|
||||
* @return {TypedArray}
|
||||
*/
|
||||
StaticDisjointSet.prototype.mapping = function() {
|
||||
var MappingClass = helpers.getPointerArray(this.dimension);
|
||||
|
||||
var ids = {},
|
||||
mapping = new MappingClass(this.size),
|
||||
c = 0;
|
||||
|
||||
var r;
|
||||
|
||||
for (var i = 0, l = this.parents.length; i < l; i++) {
|
||||
r = this.find(i);
|
||||
|
||||
if (typeof ids[r] === 'undefined') {
|
||||
mapping[i] = c;
|
||||
ids[r] = c++;
|
||||
}
|
||||
else {
|
||||
mapping[i] = ids[r];
|
||||
}
|
||||
}
|
||||
|
||||
return mapping;
|
||||
};
|
||||
|
||||
/**
|
||||
* Method used to compile the disjoint set into an array of arrays.
|
||||
*
|
||||
* @return {array}
|
||||
*/
|
||||
StaticDisjointSet.prototype.compile = function() {
|
||||
var ids = {},
|
||||
result = new Array(this.dimension),
|
||||
c = 0;
|
||||
|
||||
var r;
|
||||
|
||||
for (var i = 0, l = this.parents.length; i < l; i++) {
|
||||
r = this.find(i);
|
||||
|
||||
if (typeof ids[r] === 'undefined') {
|
||||
result[c] = [i];
|
||||
ids[r] = c++;
|
||||
}
|
||||
else {
|
||||
result[ids[r]].push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convenience known methods.
|
||||
*/
|
||||
StaticDisjointSet.prototype.inspect = function() {
|
||||
var array = this.compile();
|
||||
|
||||
// Trick so that node displays the name of the constructor
|
||||
Object.defineProperty(array, 'constructor', {
|
||||
value: StaticDisjointSet,
|
||||
enumerable: false
|
||||
});
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
if (typeof Symbol !== 'undefined')
|
||||
StaticDisjointSet.prototype[Symbol.for('nodejs.util.inspect.custom')] = StaticDisjointSet.prototype.inspect;
|
||||
|
||||
|
||||
/**
|
||||
* Exporting.
|
||||
*/
|
||||
module.exports = StaticDisjointSet;
|
||||
Reference in New Issue
Block a user