-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathUnionFind.java
More file actions
100 lines (81 loc) · 2.19 KB
/
Copy pathUnionFind.java
File metadata and controls
100 lines (81 loc) · 2.19 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
90
91
92
93
94
95
96
97
98
99
100
/*
* Code by:@yinengy
* Time: 10/8/2018
*
* No pseudocode in the book,
* but I mainly follow the content on Section 4.6
*/
public class UnionFind {
/**
* a node with a pointer points to the set it belongs to
*/
private class Node {
private int name;
private int size; // number of descendants
/**
* @param name the name of set
*/
private Node(int name) {
this.name = name;
this.size = 0;
}
}
private Node[] set; // contains the name of the set currently containing each element, index 0 is invalid
/**
* initiate the Union-Find. Each nodes in the input S will be in separate set.
* O(n)
*
* @param S a array contain all nodes (index begin from 1 rather than 0)
*/
public UnionFind(int[] S) {
set = new Node[S.length + 1];
for (int s : S) {
set[s] = new Node(s); // each in its own set
}
}
/**
* create union-find by the number of node rather than a int[]
*/
public UnionFind(int num) {
int[] temp = new int[num];
for (int i = 0; i < num; i++) {
temp[i] = i+1;
}
set = new Node[num + 1];
for (int s : temp) {
set[s] = new Node(s); // each in its own set
}
}
/**
* make union of two sets, O(1)
*/
public void union(int a, int b) {
if (set[a].size < set[b].size) {
set[a].name = b;
} else {
set[b].name = a;
}
}
/**
* find the set that v belongs to by recursive (no path compression), O(logn)
*/
public int recursivefind(int v) {
if (set[v].name == v) {
return v;
}
return recursivefind(set[v].name);
}
/**
* find the set while doing path compression,
* O(logn) for first time, and O(nα(n)) for n subsequent calls.
* α(n) is inverse Ackermann function
*/
public int find(int v) {
int trav = v;
while (set[trav].name != trav) {
trav = set[trav].name; // find the root
}
set[v].name = trav; // compress the path
return trav;
}
}