forked from kennyledet/Algorithm-Implementations
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request kennyledet#421 from girishramnani/master
union find algorithm
- Loading branch information
Showing
1 changed file
with
86 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
|
||
|
||
|
||
public class UF { | ||
private int[] id; // id[i] = parent of i | ||
private byte[] rank; // rank[i] = rank of subtree rooted at i (cannot be more than 31) | ||
private int count; // number of components | ||
|
||
/** | ||
* Initializes an empty union-find data structure with <tt>N</tt> | ||
* isolated components <tt>0</tt> through <tt>N-1</tt> | ||
* @throws java.lang.IllegalArgumentException if <tt>N < 0</tt> | ||
* @param N the number of sites | ||
*/ | ||
public UF(int N) { | ||
if (N < 0) throw new IllegalArgumentException(); | ||
count = N; | ||
id = new int[N]; | ||
rank = new byte[N]; | ||
for (int i = 0; i < N; i++) { | ||
id[i] = i; | ||
rank[i] = 0; | ||
} | ||
} | ||
|
||
/** | ||
* Returns the component identifier for the component containing site <tt>p</tt>. | ||
* @param p the integer representing one object | ||
* @return the component identifier for the component containing site <tt>p</tt> | ||
* @throws java.lang.IndexOutOfBoundsException unless <tt>0 ≤ p < N</tt> | ||
*/ | ||
public int find(int p) { | ||
if (p < 0 || p >= id.length) throw new IndexOutOfBoundsException(); | ||
while (p != id[p]) { | ||
id[p] = id[id[p]]; // path compression by halving | ||
p = id[p]; | ||
} | ||
return p; | ||
} | ||
|
||
/** | ||
* Returns the number of components. | ||
* @return the number of components (between <tt>1</tt> and <tt>N</tt>) | ||
*/ | ||
public int count() { | ||
return count; | ||
} | ||
|
||
/** | ||
* Are the two sites <tt>p</tt> and <tt>q</tt> in the same component? | ||
* @param p the integer representing one site | ||
* @param q the integer representing the other site | ||
* @return true if the two sites <tt>p</tt> and <tt>q</tt> are in the same component; false otherwise | ||
* @throws java.lang.IndexOutOfBoundsException unless | ||
* both <tt>0 ≤ p < N</tt> and <tt>0 ≤ q < N</tt> | ||
*/ | ||
public boolean connected(int p, int q) { | ||
return find(p) == find(q); | ||
} | ||
|
||
|
||
/** | ||
* Merges the component containing site <tt>p</tt> with the | ||
* the component containing site <tt>q</tt>. | ||
* @param p the integer representing one site | ||
* @param q the integer representing the other site | ||
* @throws java.lang.IndexOutOfBoundsException unless | ||
* both <tt>0 ≤ p < N</tt> and <tt>0 ≤ q < N</tt> | ||
*/ | ||
public void union(int p, int q) { | ||
int i = find(p); | ||
int j = find(q); | ||
if (i == j) return; | ||
|
||
// make root of smaller rank point to root of larger rank | ||
if (rank[i] < rank[j]) id[i] = j; | ||
else if (rank[i] > rank[j]) id[j] = i; | ||
else { | ||
id[j] = i; | ||
rank[i]++; | ||
} | ||
count--; | ||
} | ||
|
||
|
||
} |