快速联合Java实现

快速联合Java实现,java,Java,我一直在研究快速联合算法。下面的代码是实现的示例。 有人能给我解释一下根方法中发生了什么吗 public class quickUnion { private int[] id; public void QuickUnionUF(int N){ id = new int [N]; for(int i = 0; i < N; i++){ id[i] = i; } } private i

我一直在研究快速联合算法。下面的代码是实现的示例。 有人能给我解释一下根方法中发生了什么吗

public class quickUnion {
    private int[] id;

    public void QuickUnionUF(int N){
        id = new int [N];
        for(int i = 0; i < N; i++){
            id[i] = i;
        }
    }

    private int root(int i){
        while (i != id[i]){
            i = id[i];
        }
        return i;
    }
    public boolean connected(int p, int q){
        return root(p) == root(q);
    }
    public void union(int p, int q){
        int i = root(p);
        int j = root(q);
        id[i] = j;
    }
}
公共类快速联合{
私有int[]id;
公共无效快速联合(内部N){
id=新的整数[N];
对于(int i=0;i
联合查找的核心原则是每个元素都属于一组不相交的元素。这意味着,如果绘制一个林(一组树),该林将包含所有元素,并且没有任何元素位于两个不同的树中

在构建这些树时,可以想象任何节点都有父节点或根节点。在联合查找的这个实现中(以及在大多数联合查找实现中),每个元素的父元素都存储在该元素索引处的数组中。因此,等同于id[i]的元素是i的父元素

你可能会问:如果我没有父母(aka是根)怎么办?在这种情况下,约定是将i设置为自身(i是其自身的父级)。因此,id[i]==i只是检查我们是否已经到达树的根

把这些放在一起,根函数从开始节点一直向上遍历树(逐父遍历),直到到达根。然后返回根

旁白:
为了使该算法更快地到达根,一般的实现将“展平”树:到达根所需的父级越少,根函数返回的速度就越快。因此,在许多实现中,您将看到一个附加步骤,其中您将元素的父元素设置为其原始祖辈(id[i]=id[id[i]])

这里算法的要点是:始终保持一个顶点的根等于它本身

  • 初始化:Init id[i]=i。每个顶点本身就是一个根
  • 合并根目录:

    • 如果我们合并根5和根6。假设我们想要将根6合并到根5中。所以id[6]=5。id[5]=5。-->5是根
    • 如果我们继续合并4到6。id[4]=4->基本根目录。id[6]=5。->不是基根。我们继续发现:id[5]=5->base root。所以我们分配id[4]=6

  • 在所有情况下,我们始终保持约定:如果x是基根,
    id[x]==x
    这是算法的要点。

    来自课程中提供的Pdf文件

    i的根是id[id[id[…id[i]…]].

    根据给出的例子

      public int root(int p){
    
      while(p != id[p]){
    
          p = id[p];    
      }
      return p;
      }
    

    让我们考虑一个情况:

    id[]的元素如下所示

    现在让我们打电话

        root(3)
    
    循环内根法的干运行为:

    /**
    *快速查找Java实现的方法
    */
    包com.weekone.union.quickfind;
    导入java.util.Random;
    /**
    *@作者Ishwar Singh
    *
    */
    公共类UnionQuickFind{
    私有int[]项sarr;
    公共UnionQuickFind(){
    System.out.println(“调用:“+UnionQuickFind.class”);
    }
    公共联合快速查找(int n){
    itemsArr=新整数[n];
    }
    //p和q是指数
    公共操作(int p,int q){
    //显示阵列(itemsArr);
    int tempValue=itemsArr[p];
    如果(!断开连接(p,q)){
    itemsArr[p]=itemsArr[q];
    for(int i=0;i”);
    用于(int i:itemsArr){
    系统输出打印(i+“,”);
    }
    }
    私有void显示数组(int p、int q、字符串消息){
    System.out.println();
    系统输出打印(“{+p+”“+q+”}->“+消息);
    }
    公共无效初始值设定项array(){
    随机=新随机();
    for(int i=0;i”);
    用于(int i:itemsArr){
    系统输出打印(i+“,”);
    }
    System.out.println();
    }
    }
    主要类别:-
    /**
    * 
    */
    包com.weekone.union.quickfind;
    /**
    *@作者Ishwar Singh
    *
    */
    公共类UQF客户端{
    /**
    *@param args
    */
    公共静态void main(字符串[]args){
    int[]arr={0,1,2,3,4,5,6,7,8,9};
    int n=10;
    UnionQuickFind UnionQuickFind=新的UnionQuickFind(n);
    //unionQuickFind.initializeArray();
    unionQuickFind.initializeArray(arr);
    unionQuickFind.displayArray();
    unionQuickFind.unionOperation(4,3);
    unionQuickFind.unionOperation(3,8);
    unionQuickFind.unionOperation(6,5);
    unionQuickFind.unionOperation(9,4);
    unionQuickFind.unionOperation(2,1);
    unionQuickFind.unionOperation(8,9);
    unionQuickFind.connected(5,0);
    联合快速金融