在进行合并操作的时候,我们不是随意的把第二棵树连接到第一棵树,而是记下每棵树的节点数,合并的时候,总是要把结点数较少的树连接到节点数较大的数上。这个改变需要修改的代码稍微多一点,而且还需要一个数组来存放节点数,但是使程序的效率提高不少,我们把这个算法称为“加权快速合并算法”。
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条连线。
时间: 2024-10-06 08:07:30