联合查找数据结构

编程入门 行业动态 更新时间:2024-10-17 00:27:49
本文介绍了联合查找数据结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 对于许多问题,我看到解决方案是使用union-find数据结构。我试图阅读它,并考虑如何实现(使用C ++)。我目前的理解是,它只不过是一套集合。所以要找到属于哪一个元素,我们需要 n * log n 操作。当我们必须执行工会时,我们必须找到需要合并的两个集合,并对它们执行一个 set_union 。这对我来说看起来并不高效。我对这个数据结构的理解是正确的还是我缺少某些东西?

解决方案

这是很晚的回复,但这可能不是在stackoverflow上的其他地方已被回答,由于这是搜索union-find的人的最多页面,这里是详细的解决方案。

Find-Union是一个非常快速的操作,在几乎不变的时间内执行。 它遵循Jeremie对路径压缩和跟踪集合大小的见解。对每个查找操作本身执行路径压缩,从而获得lg *(n)的摊销时间。 lg *就像逆Ackerman函数一样,生长非常慢,很少超过5(至少直到n <2 ^ 65535)。联合/合并集执行懒惰,只需将1根指向另一个根,特别是较小的集合的根到较大集的根,它在不间断的时间完成。

请参阅以下代码从 github/kartikkukreja/blog-codes/blob/master/src/Union%20Find%20%28Disjoint%20Set% 29%20Data%20Structure.cpp

class UF { int * id,cnt,* sz ; public: //使用N个隔离集创建一个空联合查找数据结构。 UF(int N){ cnt = N; id = new int [N]; sz = new int [N]; (int i = 0; i< N; i ++)id [i] = i,sz [i] = 1的 } 〜UF(){delete [] id;删除[] sz; } //返回对应于对象p的组件的id。 int find(int p){ int root = p; while(root!= id [root])root = id [root]; while(p!= root){int newp = id [p]; id [p] = root; p = newp; } 返回根; } //用它们的联合替换包含x和y的集合。 void merge(int x,int y){ int i = find(x); int j = find(y); if(i == j)return; //使较小的根点更大一个 if(sz [i]< sz [j]){id [i] = j,sz [j] + = sz [i]; } else {id [j] = i,sz [i] + = sz [j]; } cnt--; } //对象x和y在同一个集合? bool connected(int x,int y){return find(x)== find(y); } //返回不相交集的数量。 int count(){return cnt; } };

如果您愿意,请投票或接受。

For many problems I see the solution recommended is to use a union-find data structure. I tried to read about it and think about how it is implemented (using C++). My current understanding is that it is nothing but a list of sets. So to find which set an element belongs we require n*log n operations. And when we have to perform union, then we have to find the two sets which needs to be merged and do a set_union on them. This doesn't look terribly efficient to me. Is my understanding of this data structure correct or am I missing something?

解决方案

This is quite late reply, but this has probably not been answered elsewhere on stackoverflow, and since this is top most page for someone searching for union-find, here is the detailed solution.

Find-Union is a very fast operation, performing in near constant time. It follows Jeremie's insights of path compression, and tracking set sizes. Path compression is performed on each find operation itself, thereby taking amortized lg*(n) time. lg* is like the inverse Ackerman function, growing so very slow that it is rarely beyond 5 (at least till n< 2^65535). Union/Merge sets is performed lazy, by just pointing 1 root to another, specifically smaller set's root to larger set's root, which is completed in constant time.

Refer the below code from github/kartikkukreja/blog-codes/blob/master/src/Union%20Find%20%28Disjoint%20Set%29%20Data%20Structure.cpp

class UF { int *id, cnt, *sz; public: // Create an empty union find data structure with N isolated sets. UF(int N) { cnt = N; id = new int[N]; sz = new int[N]; for (int i = 0; i<N; i++) id[i] = i, sz[i] = 1; } ~UF() { delete[] id; delete[] sz; } // Return the id of component corresponding to object p. int find(int p) { int root = p; while (root != id[root]) root = id[root]; while (p != root) { int newp = id[p]; id[p] = root; p = newp; } return root; } // Replace sets containing x and y with their union. void merge(int x, int y) { int i = find(x); int j = find(y); if (i == j) return; // make smaller root point to larger one if (sz[i] < sz[j]) { id[i] = j, sz[j] += sz[i]; } else { id[j] = i, sz[i] += sz[j]; } cnt--; } // Are objects x and y in the same set? bool connected(int x, int y) { return find(x) == find(y); } // Return the number of disjoint sets. int count() { return cnt; } };

Kindly up-vote or accept if you like.

更多推荐

联合查找数据结构

本文发布于:2023-11-30 09:22:06,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1649489.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据结构

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!