There is a “Weighted Quick-Union with Path Compression” algorithm.
The code:
public class WeightedQU
{
private int[] id;
private int[] iz;
public WeightedQU(int N)
{
id = new int[N];
iz = new int[N];
for(int i = 0; i < id.length; i++)
{
iz[i] = i;
id[i] = i;
}
}
public int root(int i)
{
while(i != id[i])
{
id[i] = id[id[i]]; // this line represents "path compression"
i = id[i];
}
return i;
}
public boolean connected(int p, int q)
{
return root(p) == root(q);
}
public void union(int p, int q) // here iz[] is used to "weighting"
{
int i = root(p);
int j = root(q);
if(iz[i] < iz[j])
{
id[i] = j;
iz[j] += iz[i];
}
else
{
id[j] = i;
iz[i] += iz[j];
}
}
}
Questions:
-
How does the path compression work?
id[i] = id[id[i]]means that we reach only the second ancester of our node, not the root. -
iz[]contains integers from0toN-1. How doesiz[]help us know the number of elements in the set?
Can someone clarify this for me?
First understand that
idis a forest.id[i]is the parent ofi. Ifid[i] == iit means thatiis a root.For some root
i(whereid[i] == i) theniz[i]is the number of elements in the tree rooted ati.As we are ascending the tree to find the root we move nodes from their parents to their grandparents. This partially flattens the tree. Notice that this operation doesn’t change which tree the node is a member of, this is all we are interested in. This is the path compression technique.
(You did notice the loop right?
while(i == id[i])terminates onceiis a root node)There is a transcription error in the code:
This is the correct version:
iz[i]is the number of elements for a tree rooted ati(or ifiis not a root theniz[i]is undefined). So it should be initialized to1, noti. Initially each element is a seperate “singleton” tree of size1.