【问题标题】:Weighted Quick-Union with Path Compression algorithm-Union Find带路径压缩算法的加权快速联合 - 联合查找
【发布时间】:2022-10-23 17:08:11
【问题描述】:

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

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 查找(int v)
  2. 无效联合(int v,int u)
  3. setCount(int v)

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


【问题讨论】:

    标签: java algorithm union-find


    【解决方案1】:

    这里有一些问题:

    • 未使用size 信息,但该信息对于保持所需性能至关重要。最重要的是,在unite

      • size 应该保持更新:联合集的成员数量将与两个给定集的成员数量一样多
      • size 应该确定两个根节点中的哪一个应该是联合集的根,因为这将使树保持平衡
    • setCount 的时间复杂度为 O(n)。如果您在成员变量中跟踪该数字,它可以在 O(1) 时间内提供信息。我称之为numSets。如果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;
        }
    }
    

    【讨论】:

      【解决方案2】:

      奥拉斯顿基里奥卢卡!!!!!!!!!!!!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多