在进行合并操作的时候,我们不是随意的把第二棵树连接到第一棵树,而是记下每棵树的节点数,合并的时候,总是要把结点数较少的树连接到节点数较大的数上。这个改变需要修改的代码稍微多一点,而且还需要一个数组来存放节点数,但是使程序的效率提高不少,我们把这个算法称为“加权快速合并算法”。
public class QuickUW
{
public static void main(String[] args)
{
int N=Integer.parseInt(args[0]);
int id[]=new int[N],sz[]=new int[N];
for(int i=0;i<N;i++)
{
id[i]=i;
sz[i]=1;
}
for(In.init();!In.empty();)
{
int i,j,p=In.getInt(),q=In.getInt();
for(i=p;i!=id[i];i=id[i]);
for(j=q;j!=id[i];j=id[j]);
if(i==j) continue;
if(sz[i]<sz[j])
{
id[i]=j;
sz[j]+=sz[i];
}
else
{
id[j]=i;
sz[j]+=sz[j];
}
}
}
加权快速合并算法所构建的森林,树中的路径比未加权合并算法中树的路径短很多。最坏情况下时,要合并的集合大小总是相等(集合大小是2的幂)。虽然这种树的结构看起来复杂,但他们有一个简单的性质,即在一棵具有2的n次幂结点的树中,要到达树根所需经过的最大的连接数是n。
性质:加权快速合并算法要判断N个对象中的两个对象是否是连接的,至多经过2lgN条连线。
转载于:https://blog.51cto.com/flyingfish/1622575