C# 不相交集在C语言中的实现#

C# 不相交集在C语言中的实现#,c#,.net,disjoint-sets,C#,.net,Disjoint Sets,我在C#中没有找到任何很好的不相交集的实现,使用按秩并集实现,所以我实现了自己的。它在O(logn)时间复杂度下工作 是否有更快的(或C#中内置的实现)或我可以使用自己的实现 class DisjointSetUBR { int[] parent; int[] rank; // height of tree public DisjointSetUBR(int[] arr) { parent = new int[arr.Length +1];

我在C#中没有找到任何很好的不相交集的实现,使用按秩并集实现,所以我实现了自己的。它在O(logn)时间复杂度下工作

是否有更快的(或C#中内置的实现)或我可以使用自己的实现

class DisjointSetUBR
{
    int[] parent;
    int[] rank; // height of tree

    public DisjointSetUBR(int[] arr)
    {
        parent = new int[arr.Length +1];
        rank = new int[arr.Length + 1];
    }

    public void MakeSet(int i)
    {
        parent[i] = i;
    }

    public int Find(int i)
    {
        while (i!=parent[i]) // If i is not root of tree we set i to his parent until we reach root (parent of all parents)
        {
            i = parent[i]; 
        }
        return i;
    }

    // Path compression, O(log*n). For practical values of n, log* n <= 5
    public int FindPath(int i)
    {
        if (i!=parent[i])
        {
            parent[i] = FindPath(parent[i]);
        }
        return parent[i];
    }

    public void Union(int i, int j)
    {
        int i_id = Find(i); // Find the root of first tree (set) and store it in i_id
        int j_id = Find(j); // // Find the root of second tree (set) and store it in j_id

        if (i_id == j_id) // If roots are equal (they have same parents) than they are in same tree (set)
        {
            return;
        }

        if (rank[i_id] > rank[j_id]) // If height of first tree is larger than second tree
        {
            parent[j_id] = i_id; // We hang second tree under first, parent of second tree is same as first tree
        }
        else
        {
            parent[i_id] = j_id; // We hang first tree under second, parent of first tree is same as second tree
            if (rank[i_id] == rank[j_id]) // If heights are same
            {
                rank[j_id]++; // We hang first tree under second, that means height of tree is incremented by one
            }
        }
    }
}
类不相交Tubr
{
int[]父母;
int[]秩;//树的高度
公共断开连接选项卡(int[]arr)
{
父项=新整数[arr.Length+1];
秩=新整数[arr.Length+1];
}
公共void生成集(int i)
{
父[i]=i;
}
公共整数查找(整数i)
{
while(i!=parent[i])//如果我不是树的根,我们将i设置为他的父,直到我们到达根(所有父的父)
{
i=父母[i];
}
返回i;
}
//路径压缩,O(log*n)。对于n的实际值,log*n秩[j_id])//若第一棵树的高度大于第二棵树的高度
{
父[j_id]=i_id;//我们将第二棵树挂在第一棵树下,第二棵树的父树与第一棵树相同
}
其他的
{
parent[i_id]=j_id;//我们将第一棵树挂在第二棵树下,第一棵树的父树与第二棵树相同
if(秩[i_id]==秩[j_id])//如果高度相同
{
rank[j_id]++;//我们将第一棵树挂在第二棵树下,这意味着树的高度增加了一
}
}
}
}
  • 在Sedgewick教授的“算法”一书中,他用 路径压缩“它应该具有反向Ackermann函数,用于查找/合并的摊销时间

  • 您是对的,在.Net中没有任何不相交集的实现


  • O(log*n)是理论上最好的AFAIK。因此,就时间复杂性而言,这是不可能做得更好的。在我看来,这似乎很好(我没有准确地检查它,但它具有按秩和路径压缩联合的预期功能),但代码审查应该在。为什么构造器使用一个它不使用的数组?实际上这里有一件小事:联合可以使用find的路径压缩变量。@harold我在构造器中使用数组只是为了初始化数组“parent”和“rank”,因为这两个数组的长度与初始数组的长度相同。所以你可以直接传入长度,对吗?为什么是阵列?