forked from TheAlgorithms/JavaScript
- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathUnionFind.js
More file actions
Latest commit
89 lines (88 loc) · 3.09 KB
/
Copy pathUnionFind.js
File metadata and controls
89 lines (88 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/**
* union find data structure for javascript
*
* In computer science, a disjoint-set data structure, also called a union–find data structure or merge–find set,
* is a data structure that stores a collection of disjoint (non-overlapping) sets. Equivalently, it stores a partition
* of a set into disjoint subsets. It provides operations for adding new sets, merging sets (replacing them by their union),
* and finding a representative member of a set.
* The last operation allows to find out efficiently if any two elements are in the same or different sets.
*
* Disjoint-set data structures play a key role in Kruskal's algorithm for finding the minimum spanning tree of a graph.
* The importance of minimum spanning trees means that disjoint-set data structures underlie a wide variety of algorithms.
* In addition, disjoint-set data structures also have applications to symbolic computation, as well in compilers,
* especially for register allocation problems.
*
* you can learn more on disjoint-set / union–find data structure at https://en.wikipedia.org/wiki/Disjoint-set_data_structure
*/
functionUnionFind(n,key){
if(!(thisinstanceofUnionFind))returnnewUnionFind(n)
if(key&&typeofkey!=='function'){
thrownewError('key has to be a function or else left undefined')
}
letcnt,length
// init Union Find with number of distinct groups. Each group will be referred to as index of the array of size 'size' starting at 0.
// Provide an optional key function that maps these indices. I.e. for the groups starting with 1 provide function(a){return a-1;}. The default value is function(a){return a;}.
key=
key||
function(a){
returna
}
cnt=length=n
constid=newArray(n)
constsz=newArray(n)
for(leti=0;i<n;i++){
id[i]=i
sz[i]=1
}
// Returns the number of elements of uf object.
this.size=function(){
returnlength
}
// Returns the number of distinct groups left inside the object.
this.count=function(){
returncnt
}
// Return the root (value) of the group in which p is.
this.find=function(p){
p=key(p)
while(p!==id[p]){
id[p]=id[id[p]]
p=id[p]
}
returnp
}
// Returns true if p and p are both in same group, false otherwise.
this.connected=function(p,q){
p=key(p)
q=key(q)
ensureIndexWithinBounds(p,q)
returnthis.find(p)===this.find(q)
}
// Combine elements in groups p and q into a single group. In other words connect the two groups.
this.union=function(p,q){
p=key(p)
q=key(q)
ensureIndexWithinBounds(p,q)
consti=this.find(p)
constj=this.find(q)
if(i===j)return
if(sz[i]<sz[j]){
id[i]=j
sz[j]+=sz[i]
}else{
id[j]=i
sz[i]+=sz[j]
}
cnt--
}
functionensureIndexWithinBounds(args){
for(leti=arguments.length-1;i>=0;i--){
constp=arguments[i]
if(p>=length)
thrownewError(
'Index out of bounds. The maximum index can be length-1'
)
}
}
}
export{UnionFind}