【问题标题】:Disjoint Set implementation in C#C#中的不相交集实现
【发布时间】:2018-03-05 02:56:25
【问题描述】:

我没有在 C# 中使用 Union by rank implementation 找到 Disjoint Set 的任何好的实现,所以我自己实现了。它的工作时间复杂度为 O(log n)。

是否有更快的(或 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
            }
        }
    }
}

【问题讨论】:

  • O(log* n) 是理论上最好的 AFAIK。所以就时间复杂度而言,不可能做得更好。
  • 对我来说看起来差不多(我没有检查得那么准确,但它具有按等级和路径压缩联合的预期功能),但代码审查应该在 code reviews 上进行。为什么构造函数会采用一个它不使用的数组?
  • 其实这里有个小事情:联合可以使用 find 的路径压缩变体。
  • @harold 我在构造函数中使用数组只是为了初始化数组“parent”和“rank”,因为这两个数组的长度与初始数组相同。
  • 所以你可以只传递长度对吗?为什么是数组?

标签: c# .net disjoint-sets


【解决方案1】:
  1. 在 Sedgewick 教授的“算法”书中,他mentions“加权快速联合与 路径压缩”,它应该具有反阿克曼函数摊销时间用于查找/联合。

  2. 你是对的,.Net 中没有任何不相交集的实现。

【讨论】:

    猜你喜欢
    • 2019-05-31
    • 1970-01-01
    • 2011-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多