1.5.13使用路径压缩的加权quick-union算法。修改加权quick-union算法(算法1.5),实现如练习1.5.12所述的路径压缩。给出一列输入,使该方法能够产生一棵高度为4的树。注意:访算法的所有操作的均摊成本已知被限制在反Ackermann函数的范围之内,且对于实际应用中可能出现的所有N值均小于5。
答:
1-0
3-2
3-1
5-4
7-6
7-5
7-3
9-8
11-10
11-9
13-12
15-14
15-13
15-11
15-7
tinyUF.txt
16
1
0
3
2
3
1
5
4
7
6
7
5
7
3
9
8
11
10
11
9
13
12
15
14
15
13
15
11
15
7
public class E1d5d13
{
private int[] id;
private int[] sz;
private int count;
public E1d5d13(int N)
{
count=N;
id=new int[N];
for (int i=0;i<N;i++)
id[i]=i;
//
sz=new int[N];
for (int i=0;i<N;i++)
sz[i]=1;
//
}
public int count()
{return count;}
boolean connected(int p,int q)
{return find(p)==find(q);}
public int find(int p)
{
while(p!=id[p]) p=id[p];
int root=p;
int temp;
while(p!=id[p])
{
temp=id[p];
id[p]=root;
p=temp;
}
return root;
}
public void union(int p,int q)
{
int i=find(p);
int j=find(q);
if(i==j) return;
if(sz[i]<sz[j])
{
id[i]=j;
sz[j]=sz[j]+sz[i];
}
else
{
id[j]=i;
sz[i]=sz[i]+sz[j];
}
count--;
//
for (int k=0;k<id.length;k++)
StdOut.printf("%3d",id[k]);
StdOut.println();
}
public static void main(String[] qrgs)
{
int N=StdIn.readInt();
E1d5d13 uf=new E1d5d13(N);
while (!StdIn.isEmpty())
{
int p=StdIn.readInt();
int q=StdIn.readInt();
if(uf.connected(p,q)) continue;
StdOut.printf("p=%d q=%d
",p,q);
uf.union(p,q);
}//end while
}//end main
}//end class