Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带路径压缩算法的加权快速并集_Java_Algorithm_Union Find - Fatal编程技术网

Java 带路径压缩算法的加权快速并集

Java 带路径压缩算法的加权快速并集,java,algorithm,union-find,Java,Algorithm,Union Find,有一种“带路径压缩的加权快速并集”算法 守则: public class WeightedQU { private int[] id; private int[] iz; public WeightedQU(int N) { id = new int[N]; iz = new int[N]; for(int i = 0; i < id.length; i++) { i

有一种“带路径压缩的加权快速并集”算法

守则:

public class WeightedQU 
{
    private int[] id;
    private int[] iz;

    public WeightedQU(int N)
    {
        id = new int[N];
        iz = new int[N];
        for(int i = 0; i < id.length; i++)
        {
            iz[i] = i;
            id[i] = i;
        }
    }

    public int root(int i)
    {
        while(i != id[i])
        {
            id[i] = id[id[i]];   // this line represents "path compression"
            i = id[i];
        }
        return i;
    }

    public boolean connected(int p, int q)
    {
        return root(p) == root(q);
    }

    public void union(int p, int q)   // here iz[] is used to "weighting"
    {
        int i = root(p);
        int j = root(q);
        if(iz[i] < iz[j])
        {
            id[i] = j;
            iz[j] += iz[i];
        }
        else
        {
            id[j] = i;
            iz[i] += iz[j];
        }
    }
}
公共类权重dqu
{
私有int[]id;
私有int[]iz;
公共权重QU(整数N)
{
id=新的整数[N];
iz=新整数[N];
for(int i=0;i
问题:

  • 路径压缩是如何工作的
    id[i]=id[id[i]
    意味着我们只到达节点的第二个节点,而不是根节点

  • iz[]
    包含从
    0
    N-1
    的整数。
    iz[]
    如何帮助我们知道集合中元素的数量


  • 有人能帮我澄清一下吗?

    首先要了解
    id
    是一个森林
    id[i]
    i
    的父项。如果
    id[i]==i
    ,则表示
    i
    是根

    对于某些根
    i
    (其中
    id[i]==i
    ),则
    iz[i]
    树中以
    i
    为根的元素数

    public int root(int i)
    {
        while(i != id[i])
        {
            id[i] = id[id[i]];   // this line represents "path compression"
            i = id[i];
        }
        return i;
    }
    
    路径压缩是如何工作的
    id[i]=id[id[i]
    意味着我们只到达节点的第二个节点,而不是根节点

    当我们在树上查找根时,我们将节点从其父节点移动到其祖父母节点。这部分压平了树。请注意,此操作不会更改节点所属的树,这是我们感兴趣的全部内容。这是路径压缩技术

    (您确实注意到循环正确吗?
    而(i==id[i])
    终止一次
    i
    是根节点)

    iz[]
    包含从
    0
    N-1
    的整数。
    iz[]
    如何帮助我们知道集合中元素的数量

    代码中存在转录错误:

    for(int i = 0; i < id.length; i++)
    {
        iz[i] = i; // WRONG
        id[i] = i;
    }
    
    for(int i=0;i
    这是正确的版本:

    for(int i = 0; i < id.length; i++)
    {
        iz[i] = 1; // RIGHT
        id[i] = i;
    }
    
    for(int i=0;i
    iz[i]
    是以
    i
    为根的树的元素数(或者如果
    i
    不是根,则
    iz[i]
    未定义)。因此它应该初始化为
    1
    ,而不是
    i
    。最初,每个元素都是一个大小为
    1

    问题1的独立“单体”树。 说行id[i]=id[id[i]]是不对的;仅到达根的第二个祖先。您将认识到,while循环while(i!=id[i])仅在节点i指向根时停止,即当i==id[i]时。此时,我们将使用线id[i]=id[i]]将节点指向根;其中,内部id[i]是根

    问题2

    初始化iz[i]=i是错误的;实际上它应该是iz[i]=1;也就是说,每个节点大小在开始时都由1初始化,因为它们的大小为1。
    在并集函数中,你会发现我们有直线iz[j]+=iz[i];和iz[i]+=iz[j];它将根节点的大小更新为连接在一起的两个组件的大小之和。这将有效地更新节点大小。

    id[i]=id[id[i]];//这一行表示“路径压缩”

    上面的代码是“更简单的单通变量”,如联合查找幻灯片(Kevin Wayne和Robert Sedgewick的算法,第一部分)中所述。因此,你对问题1的猜测是正确的。每个被检查的节点都指向其祖辈节点

    要使每个被检查的节点指向根,我们需要两次通过实现:

      /**
     * Returns the component identifier for the component containing site <tt>p</tt>.
     * @param p the integer representing one site
     * @return the component identifier for the component containing site <tt>p</tt>
     * @throws java.lang.IndexOutOfBoundsException unless 0 <= p < N
     */
    public int find(int p) {
        int root = p;
        while (root != id[root])
            root = id[root];
        while (p != root) {
            int newp = id[p];
            id[p] = root;
            p = newp;
        }
        return root;
    }
    
    /**
    *返回包含站点p的组件的组件标识符。
    *@param p表示一个站点的整数
    *@返回包含站点p的组件的组件标识符
    
    *@throws java.lang.IndexOutOfBoundsException,除非0还有一点需要注意:

    当我们在做
    id[i]=id[id[i]]
    i.e;让我成为它的祖父母

    -然后,
    id[i]
    的大小将减小i,e的大小<代码>iz[id[i]]-=iz[i]

    现在,这使得代码完全正确

    我对此不确定,但直觉上我觉得,
    它的缺失不会引起问题,因为我们总是比较根的大小。

    阅读c/c++中的算法,第1-4部分,robert sedgewick,第1章,很好的解释。关于路径压缩,这是路径压缩的一种单遍变体,使路径中的每一个节点指向其祖辈节点(将路径长度减半)两次传递更像是在root()中添加第二个循环,将每个被检查节点的id[]设置为root。似乎有必要补充一下。