week1 Union-Find
problem:
Given a set of N objects.
Union command: connect two objects.
Find/connected query: is there a path connecting the two objects?
Quick-find [eager approach]
public class QuickFindUF
{
private int[] id;
public QuickFindUF(int N)
{
id = new int[N];
for(i=0;i<N;i++)
id[i]=i;
}
public boolean connected(int p, int q)
{
return id[p]=id[q];
}
public void union(int p, int q)
{
int pid=id[p];
int qid=id[q];
for(int i=0;i<id.length;i++)
{
if(id[i]==pid) id[i]=qid;
}
}
}
Quick-Union [lazy approach]
public class QuickUnionUF
{
private int[] id;
public QuickUnionUF(int N)
{
id = new int[N];
for(int i=0;i<N;i++) id[i]=i;
}
private int root(int i)
{
while(i != id[i]) i = id[i];
return i;
}
public boolean connected(int p,int q)
{
return root(p) == root(q);
}
public void union(int p, int q)
{
int i = root(p);
int j = root(q);
id[i]=j;
}
}
Weighted Quick-Union with path compression
public class weightedQuickUnionUF
{
private int[] id;// id[i]=parent of i
private int[] sz;// sz[i]= size of sites in trees rooted at i
public weightedQuickUnionUF(int N)
{
id = new int[];
sz = new int[];
for(int i=0;i<N;i++)
{
id[i]=i;
sz[i]=1;
}
}
public int root(int i)
{
while(i != id[i])
{
i=id[id[i]]; // this is for 'path compression'
return i;
}
}
public boolean connected(int p, int q)
{
return root(p)==root(q);
}
public void union(int p, int q)
{
int i = root(p);
int j = root(q);
if(sz[i]>sz[j])
{
id[j]=i;
sz[i]+=sz[j];
}
else
{
id[i]=j;
sz[j]+=sz[i];
}
}
public static void main(Strings args[])
{
int N = StdIn.readInt();
weightedQuickUnionUF uf = weightedQuickUnionUF(N);
while(!StdIn.isEmpty())
{
int p = StdIn.readInt();
int q = StdIn.readInt();
if(uf.connected(p,q)) continue;
uf.union(p,q);
StdOut.println(p + ' '+q);
}
}
}