Answer:
Step-by-step explanation:
package net.qiguang.algorithms.C1_Fundamentals.S5_CaseStudyUnionFind;
import java.util.Random;
/**
* 1.5.20 Dynamic growth.
* Using linked lists or a resizing array, develop a weighted quick-union implementation that
* removes the restriction on needing the number of objects ahead of time. Add a method newSite()
* to the API, which returns an int identifier
*/
public class Exercise_1_5_20 {
public static class WeightedQuickUnionUF {
private int[] parent; // parent[i] = parent of i
private int[] size; // size[i] = number of sites in subtree rooted at i
private int count; // number of components
int N; // number of items
public WeightedQuickUnionUF() {
N = 0;
count = 0;
parent = new int[4];
size = new int[4];
}
private void resize(int n) {
int[] parentCopy = new int[n];
int[] sizeCopy = new int[n];
for (int i = 0; i < count; i++) {
parentCopy[i] = parent[i];
sizeCopy[i] = size[i];
}
parent = parentCopy;
size = sizeCopy;
}
public int newSite() {
N++;
if (N == parent.length) resize(N * 2);
parent[N - 1] = N - 1;
size[N - 1] = 1;
return N - 1;
}
public int count() {
return count;
}
public int find(int p) {
// Now with path compression
validate(p);
int root = p;
while (root != parent[root]) {
root = parent[root];
}
while (p != root) {
int next = parent[p];
parent[p] = root;
p = next;
}
return p;
}
// validate that p is a valid index
private void validate(int p) {
if (p < 0 || p >= N) {
throw new IndexOutOfBoundsException("index " + p + " is not between 0 and " + (N - 1));
}
}
public boolean connected(int p, int q) {
return find(p) == find(q);
}
public void union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
if (rootP == rootQ) {
return;
}
// make smaller root point to larger one
if (size[rootP] < size[rootQ]) {
parent[rootP] = rootQ;
size[rootQ] += size[rootP];
} else {
parent[rootQ] = rootP;
size[rootP] += size[rootQ];
}
count--;
}
}
public static void main(String[] args) {
WeightedQuickUnionUF uf = new WeightedQuickUnionUF();
Random r = new Random();
for (int i = 0; i < 20; i++) {
System.out.printf("\n%2d", uf.newSite());
int p = r.nextInt(i+1);
int q = r.nextInt(i+1);
if (uf.connected(p, q)) continue;
uf.union(p, q);
System.out.printf("%5d-%d", p, q);
uf.union(r.nextInt(i+1), r.nextInt(i+1));
}
}
}