There is a \"Weighted Quick-Union with Path Compression\" algorithm.
The code:
public class WeightedQU
{
private int[] id;
private int[] iz;
id[i] = id[id[i]]; // this line represents "path compression"
The above code is "Simpler one-pass variant" as mentioned in the slide of Union Find (Algorithms, Part I by Kevin Wayne and Robert Sedgewick). Therefore your guess for question 1 is correct. Each examined node points to its grandparent.
To make each examined node points to the root we will need two-pass implementation:
/**
* Returns the component identifier for the component containing site p.
* @param p the integer representing one site
* @return the component identifier for the component containing site p
* @throws java.lang.IndexOutOfBoundsException unless 0 <= p < N
*/
public int find(int p) {
int root = p;
while (root != id[root])
root = id[root];
while (p != root) {
int newp = id[p];
id[p] = root;
p = newp;
}
return root;
}
Reference: http://algs4.cs.princeton.edu/15uf/WeightedQuickUnionPathCompressionUF.java.html