Java 实现联合查找算法

Java 实现联合查找算法,java,kruskals-algorithm,union-find,Java,Kruskals Algorithm,Union Find,我正在尝试为Kruskal实现一个联合查找alg。我使用的是这个伪代码,我不理解下面的union部分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)

我正在尝试为Kruskal实现一个联合查找alg。我使用的是这个伪代码,我不理解下面的union部分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];
            }
        }
    }
公共类UnionFind{
私人int[]_boss;
私有int[]_大小;
私有int[]_集;
公共联合查找(int max)
{
_boss=新整数[max];
_大小=新整数[最大值];
_设置=新整数[max];
}
公共void init(Set vertSet)
{
//对于每个顶点,请执行以下操作:
int j=0;
for(int i:vertSet)
{
_boss[j]=i;
_尺寸[j]=1;
_set[j]=i;
j++;
}
}
整数查找(整数u)
{
返回(_boss[u]);
}
无效并集(整数u,整数v)
{
如果(_size[_boss[u]]>_size[_boss[v]])
{
_set[_boss[u]=_set[_boss[u]];
//_设置[_boss[v]];
_大小[_boss[u]+=_大小[_boss[v]];

对于(intz=0;z第2步意味着集合u现在成为u和v的并集,因此不能指定集合[v]=集合[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]]);
ArrayList set[]=新的ArrayList[max];
//初始化每个集合,将元素添加到集合中
对于(int i=0;i
最后一点是,您的步骤4是错误的,对于您当前的实现,您只需将每个元素添加到集合[boss[u]],但在这一步中,它们只需要集合[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];
        }
int-bossV=boss[v];//这很重要!回答自己为什么需要这个。

对于(int z=0;zThanks,我有关于这个主题最差的书,除了wiki和一本更好的书?那么,第2步是一个双数组吗?我一点也不理解这一点。@Dixon Steel嗯,你可以试着看看这个或这个经典的,谢谢,找到了一个更好的版本,实现了一些压缩,这对我的理解更直接是的,到目前为止似乎还有效。