当前位置: 首页 > 知识库问答 >
问题:

带路径压缩算法的加权快速联合-联合查找

居英资
2023-03-14

我有一个项目,我必须实现一个带有路径压缩算法的加权快速并集。在看到其他一些源代码后,我最终得到了这个:

public class UnionFind {

private int[] parent;
private int[] size;
private int maxItemCount;      // maximum number of items from {0,1,...,N-1}
private int numItems;      // number of items created

UnionFind(int N) {
    this.N = N;
    this.K = 0;
    parent = new int[N];
    size = new int[N];
    for (int i = 0; i < N; i++) {
        parent[i] = -1;
        size[i] = 0;
    }
}

void makeSet(int v) {
    if (parent[v] != -1) return; // item v already belongs in a set
    parent[v] = v;
    size[v] = 1;
    K++;
}

int find(int v) {
    if (v == parent[v]) {
        return v;
    }
       return parent[v] = find(parent[v]);
    }


void unite(int v, int u) {
    int x=find(v);
    int y=find(u);
    if(x!=y) {
        parent[x]=y;
    }
}

int setCount() {
    int item=0;
    for(int i=0;i<parent.length;i++) {
        if(i==parent[i]) {
            item++;
        }
    }
    return item; // change appropriately 
}

int itemCount() {
    return K;
}

分配给我的任务是正确完成以下方法:

  1. int find(int v)
  2. void unite(int v,int u)
  3. setCount(int v)

嗯,算法似乎很慢,我找不到合适的解决方案

共有1个答案

盖嘉珍
2023-03-14

以下是一些问题:

>

  • 未使用大小信息,但该信息对于保持所需的性能至关重要。最重要的是,团结起来

    • 大小应保持更新:联合集的成员数与两个给定集的成员数目相同
    • <code>size</code>应该确定两个根节点中的哪一个应该是联合集的根,因为这将保持树的平衡

    设置计数具有 O(n) 时间复杂度。它可以在O(1)时间内提供信息,如果你要在成员变量中跟踪这个数字。我称之为数字集。如果 setCount() 被调用很多,则此更改将产生积极的影响。

    没问题,但是将变量命名为NK无助于使代码具有可读性。为什么不给它们真正说明它们是什么的名称,这样您就不需要在它们的定义中附上注释来给出解释了?

    以下是经过修改的代码:

    public class UnionFind {
        
        private int[] parent;
        private int[] size;
        private int maxItemCount;
        private int numItems;
        private int numSets;
        
        UnionFind(int maxItemCount) {
            this.maxItemCount = maxItemCount;
            numItems = 0;
            numSets = 0;
            parent = new int[maxItemCount];
            size = new int[maxItemCount];
            for (int i = 0; i < maxItemCount; i++) {
                parent[i] = -1;
                size[i] = 0;
            }
        }
        
        void makeSet(int v) {
            if (parent[v] != -1) return; // item v already belongs in a set
            parent[v] = v;
            size[v] = 1;
            numItems++;
            numSets++;  // Keep track of number of sets
        }
        
        int find(int v) {
            if (v == parent[v]) {
                return v;
            }
            return parent[v] = find(parent[v]);
        }
        
        void unite(int v, int u) {
            int x = find(v);
            int y = find(u);
            if (x != y) {
                numSets--; // A union decreases the set count
                // Determine which node becomes the root
                if (size[x] < size[y]) {
                    parent[x] = y;
                    size[y] += size[x]; // Adapt size
                } else {
                    parent[y] = x;
                    size[x] += size[y]; // Adapt size
                }
            }
        }
        
        int setCount() {
            return numSets; // Kept track of it
        }
        
        int itemCount() {
            return numItems;
        }
    }
    

  •  类似资料:
    • 根据Princeton booksite,带有路径压缩的加权快速联合将10^9联合对10^9对象的操作时间从一年减少到大约6秒。这个数字是怎么得出的?当我在10^8操作中运行下面的代码时,我的运行时间是61s。

    • 我正在为联合/查找结构实现快速联合算法。在“Java中的算法”一书网站上给出的实现中,普林斯顿实现在实现路径压缩(在方法中)时无法保持树的大小不变。这不应该对算法产生不利影响吗?还是我错过了什么?另外,如果我是对的,我们将如何修改大小数组?

    • 针对并集寻找不相交集的问题,提出了带路径压缩的加权快速并集算法 带路径压缩算法的加权快速并集 路径压缩会影响iz[]数组(包含以I为根的树的长度的数组)吗?

    • 处理以下问题(https://leetcode.com/problems/friend-circles/): 一个班有N个学生。他们有些是朋友,有些不是。他们的友谊本质上是可传递的。比如A是B的直接好友,B是C的直接好友,那么A就是C的间接好友,而我们定义的朋友圈就是一群直接或者间接好友的同学。 给定一个N*N矩阵M,表示班级学生之间的朋友关系。如果M[i][j]=1,则第i和第j个学生是彼此的直

    • 我正在学习联合/查找结构的“加权快速联合与路径压缩”算法。普林斯顿edu网站详细解释了该算法。这是Java的实现: 但就像网站提到它的性能一样: 定理:从空数据结构开始,任何 M 并集序列和对 N 个对象的查找操作都需要 O(N M lg* N) 时间。 证明非常困难。 但是算法仍然很简单! 但我仍然很好奇迭代对数lg*n是如何产生的。它是如何推导出来的?有人可以证明它或只是以直观的方式解释它吗?

    • 我这个星期天要参加考试,我只想确认我正在做的事情是否正确(你知道考试让我持怀疑态度) 这就是算法的工作原理: 这就是问题所在: 回想一下为不相交集开发的算法,这些不相交集来自一组n个元素。查找使用路径压缩,联合使用排名。此外,相同等级的两棵树的联合选择与第二个参数关联的根作为新根。从一个集合S={1,2,…,10}和10个不相交子集开始,每个子集都包含一个元素。a.执行后绘制最后一组树: Unio