1:quick-find算法的不足
当我们利用quick-find来解决动态联通性的问题时,至少要调用N-1次union()。而一次union()算法至少需要访问数组N+3次。所以我们访问数组的总次数为(N-1)(N+3)次,为平方级别。用来解决大型问题绝对不可能。因此,考虑对union()算法的优化。
2:quick-union算法的数据结构
quick-union算法的数据结构与quick-find算法的数据结构相差无几。都是以id[]数组作为索引。不过不同的是quick-union算法中的每个触点对应的id[]元素都是同一个分量中另一个触点的名称。这种联系叫“链接”。就像一个个指针,指向另一个元素。这种结构有点类似树。
3:quick-union算法的基本思想及代码实现
基于此,union算法就非常简单了。对于union(p,q),只要沿着各自的链接,找到他们的根触点,然后将其中一个的根触点链接到另外一个即可将两个分量合并成一个分量。
而对于find()算法只需要不断沿着id[]索引的方向查找即可。代码如下
public class QuickUnionUF {
private int[] id;
private int count; //分量数量
public QuickUnionUF(int N) {
count = N;
id = new int[N];
for(int i = 0; i < N; i++)
id[i] = i;
}
public int count() {
return count;
}
public boolean connected(int p, int q) {
return find(p) == find(q);
}
public int find(int p) { //找到节点p的根节点
while(id[p] != p)
p = id[p];
return p;
}
public void union(int p, int q) {
int pRoot = find(p);
int qRoot = find(q);
if(pRoot == qRoot) return ;
id[pRoot] = qRoot;
count--;
}
}