c++ - 如何在C++中的不交集中合并路径压缩?

标签 c++ disjoint-sets

我有这个用-1值初始化的DisjointSets类。我想在find()中实现路径压缩,以便在find()完成运行后,元素i及其在上级树中的所有祖先都指向根。我怎样才能做到这一点?

class DisjointSets {
public:
    int s[256];

    DisjointSets() { for (int i = 0; i < 256; i++) s[i] = -1; }
    int find(int i);
};

int DisjointSets::find(int i) {
  if ( s[i] < 0 ) {
    return i;
  }
  else {
    return find(s[i]);
  }
}
主要功能测试代码:
int main() {
  DisjointSets d;

  d.s[1] = 3;
  d.s[3] = 5;
  d.s[5] = 7;
  d.s[7] = -1;

  std::cout << "d.find(3) = " << d.find(3) << std::endl;
  std::cout << "d.s(1) = " << d.s[1] << std::endl;
  std::cout << "d.s(3) = " << d.s[3] << std::endl;
  std::cout << "d.s(5) = " << d.s[5] << std::endl;
  std::cout << "d.s(7) = " << d.s[7] << std::endl;

  return 0;
}
基本上,在上面的示例中,值1指向3,3指向5,5指向7,直到7指向-1。当值指向-1时,即是上树中设置的不相交的根或标识,即7是根。 1、3、5是7的祖先。

最佳答案

您可以递归执行

function Find(x)
   if x.parent != x
     x.parent := Find(x.parent)
   return x.parent
在您的情况下,一个非常基本的实现可能是
struct subset
{
    int parent;
    int rank;
};

int findSet(std::vector<subset>&s, int x)
{
    if(s[x].parent != x) 
        s[x].parent = findSet(s, s[x].parent);

    return s[x].parent;
}

关于c++ - 如何在C++中的不交集中合并路径压缩?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63547611/

相关文章:

c++ - 如何将 Boost::asio::buffer(buf, size) 与 boost 绑定(bind)一起使用?

c++ - 使用 shared_ptr 在类及其成员对象之间共享变量是一个好的解决方案吗?

c++ - 非阻塞线程同步

algorithm - O(1) 在不相交的集合数据结构中创建、查找、并集

algorithm - 图算法/不相交集

Python:在每个节点扩展的算法遍历树

c++ - 如何在 C++ 中管理不相交集合中的内存释放?

c++ - 变量的声明、定义和初始化有什么区别?

c++ - 使用 C++ 测量跨网络的 2 个应用程序之间的数据传输速率(带宽),如何获得无偏见和准确的结果?

algorithm - 是否有一个例子可以在 Omega(q log n) 中运行 Union & find algorithm without union by rank?