[英]implement Union-Find Algorithm confusion
我正在尝试为Kruskal实施联盟发现的算法。 我正在使用此伪代码,我不理解下面的联合部分step2(它不是递归调用),或者我什至很接近。 如果这种方法行不通,我可以使用任何实现方式,只要我理解即可。 提前谢谢。 U和V是我的边缘节点,目前只是整数。
Init(V)
1.for every vertex v do
2.boss[v]=v
3.size[v]=1
4.set[v]={v}
Find (u)
1.Return boss[u]
Union (u,v)
1.if size[boss[u]]>size[boss[v]] then
2.set[boss[u]]=set[boss[u]] union set[boss[v]]
3.size[boss[u]]+=size[boss[v]]
4.for every z in set[boss[v]] do
5.boss[z]=boss[u]
6.else do steps 2.-5. with u,v switched
我不了解步骤2,这是到目前为止的代码:
public class UnionFind {
private int[] _boss;
private int[] _size;
private int[] _set;
public UnionFind(int max)
{
_boss = new int[max];
_size = new int[max];
_set = new int[max];
}
public void init(Set<Integer> vertSet)
{
//for every vertex do
int j=0;
for(int i : vertSet)
{
_boss[j]=i;
_size[j]=1;
_set[j]=i;
j++;
}
}
int find(int u)
{
return(_boss[u]);
}
void union(int u, int v)
{
if(_size[_boss[u]]>_size[_boss[v]])
{
_set[_boss[u]]=_set[_boss[u]];
//_set[_boss[v]];
_size[_boss[u]]+=_size[_boss[v]];
for(int z=0;z<_boss.length;z++)
{
_boss[z]=_boss[u];
}
}
else
{
//switch u and v
_set[_boss[v]]=_set[_boss[v]];
//union(_set[_boss[v]],_set[_boss[u]]);
_size[_boss[v]]+=_size[_boss[u]];
for(int z=0;z<_boss.length;z++)
{
_boss[z]=_boss[v];
}
}
}
步骤2表示集合u现在成为u和v的并集,因此您无法分配set [v] = set [v](u和v分别是boss [u],boss [v]的缩写)。 因此,如果集合u为{u}且集合v为{v},则在此步骤之后,集合u将为{u,v},还有一个示例是集合u = {1,2},集合v = {3, 4},因此之后,将u设置为{1,2,3,4}。 根据您使用的数据结构,您将需要实现不同的实现。 一种方法是使用ArrayList
ArrayList<Integer> set[] = new ArrayList[max];
//Initialize each set, add element into set
for(int i = 0; i < max; i++)
set[i] = new ArrayList();
set[i].add(i);
//For step 2
set[boss[u]].addAll(set[boss[v]]);
最后一件事是,您的第4步是错误的,对于当前的实现,您只需将每个元素添加到set [boss [u]]中,但是在此步骤中,它们仅需要set [boss [v]]中的那些元素。 所以:
int bossV = boss[v];//This is important! Answer why this is needed by yourself.
for(int z=0;z<_boss.length;z++)
{
if(boss[z] == bossV)
_boss[z]=_boss[u];
}
小提示:您使用的这个版本不是联盟查找的最快版本,请尝试阅读更多有关它的信息!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.