Disjoint Set
Disjoint Set,最基本的操作就是 Union 和 Find 两个函数。
Union 有根据size和rank两种方法,而 Find 通常使用 path compression 来提升后续搜索的效率。
时间复杂度等可以参考 http://web.eecs.utk.edu/~plank/plank/classes/cs302/Notes/Disjoint/
实现一:建立parent数组,这样做实现起来非常简单,但是也只适用于集合元素是从0开始自然数(比如一个数组下标)。
Union 根据size合并。
#include <iostream>class DisjointSet{ public:DisjointSet(int size):parent(size,-1){}void Union(int x, int y){int root1=Find(x), root2=Find(y);if (root1==root2) return;// whoever's size is bigger becomes parent of other// notice parent[root] is negative, if parent[root] is smaller, then its size is largerif (parent[root1]>parent[root2]){parent[root2] += parent[root1];parent[root1] = root2;}else{parent[root1] += parent[root2];parent[root2] = root1;}}int Find(int x){if (parent[x]<0) return x;return parent[x] = Find(parent[x]);}private:vector<int> parent; };int main() {DisjointSet s(10);s.Union(2,1);cout << s.Find(1);return 0; }
实现二:创建一个结构体Node,成员是val和指向parent的指针。相比上一种方法的好处是,val没有限制。同时需要一个hashmap将val的值映射到Node *,用来找Node。
Union 根据rank合并。
#include <iostream>struct Node{int val;Node *parent;int rank;Node(int v):val(v),parent(this),rank(0){} };class DisjointSet{ public:// Create a set with only one elementvoid makeSet(int val){Node *node=new Node(val);m[val] = node;}// Combines two sets, unions by rankvoid unionSet(int val1, int val2){Node *node1=m[val1];Node *node2=m[val2];Node *root1=findSet(node1);Node *root2=findSet(node2);// they of part of the same set, do nothingif (root1==root2) return;// whoever's rank is higher becomes parent of otherif (root1->rank > root2->rank)root2->parent = root1;else if (root1->rank < root2->rank)root1->parent = root2->parent;else{root1->rank += 1;root2->parent = root1;}}int findSet(int val){return findSet(m[val])->val;}// Find the representative recursively and does path compression as wellNode *findSet(Node *node){Node *parent=node->parent;if (parent==node) return node;node->parent = findSet(node->parent);return node->parent;}private:unordered_map<int,Node *> m; // node val -> Node * };int main(){DisjointSet a;for (int i=1;i<=7;++i) a.makeSet(i);a.unionSet(1,2);a.unionSet(2,3);cout << a.findSet(1) << endl;cout << a.findSet(3) << endl;cout << a.findSet(7) << endl;return 0; }
应用中,可以简化Union,不用根据size,rank合并,直接把一个节点的root赋为另一个节点root的父亲即可。
转载于:https://www.cnblogs.com/hankunyan/p/9998626.html
Disjoint Set相关推荐
- 并查集(disjoint set)的实现及应用
这里有一篇十分精彩.生动的 并查集详解 (转): "朋友的朋友就是朋友"⇒ 传递性,建立连通关系 disjoint set,并查集(一种集合),也叫不相交集,同时也是一种树型的数据 ...
- 352. Data Stream as Disjoint Intervals
题目链接: https://leetcode.com/problems/data-stream-as-disjoint-intervals/ Given a data stream input of ...
- boost::geometry::disjoint用法的测试程序
boost::geometry::disjoint用法的测试程序 实现功能 C++实现代码 实现功能 boost::geometry::disjoint用法的测试程序 C++实现代码 #ifndef ...
- C++用并查集Disjoint union实现connected component连通分量(附完整源码)
C++用并查集Disjoint union实现connected component连通分量 C++用并查集Disjoint union实现connected component连通分量完整源码(定义 ...
- C++并查集Disjoint Set(附完整源码)
C++并查集Disjoint Set 并查集Disjoint Set算法的完整源码(定义,实现,main函数测试) 并查集Disjoint Set算法的完整源码(定义,实现,main函数测试) #in ...
- C语言实现并查集(Disjoint set或者Union-find set)(附完整源码)
实现实现并查集 实现并查集(Disjoint set或者Union-find set)的完整源码(定义,实现,main函数测试) 实现并查集(Disjoint set或者Union-find set) ...
- 判断2个list中是否有相同的数据(相交)Collections.disjoint
比较两个集合中是否有相同的元素,发现Collections类下的disjoint方法可以处理 Collections.disjoint() 代码如下: List<Integer> list ...
- 图论学习四之Disjoint set union并查集
分离集合 • 在有的问题中,需要对不相交的集合(disjoint set)进行这样两种操 作: • 检索某元素属于哪个集合 • 合并两个集合 • 此时,我们可以使用并查集维护这两个操作. 并查集的 ...
- 数据结构 之 并查集(Disjoint Set)
一.并查集的概念: 首先,为了引出并查集,先介绍几个概念: 1.等价关系(Equivalent Relation) 自反性.对称性.传递性. 假设a和b存在等价关系.记 ...
最新文章
- Leetcode: Maximal Rectangle
- 震惊!java中日期格式化的大坑!
- 白夜:一文看懂AI项目流程及边缘设备开发
- Fragment向ChildFragment传值
- 利用计算机绘制地质图的思路和方法,基于平面地质图的三维地质建模方法研究...
- Emacs+hideif.el 隐藏预编译代码(或彩色显示预编译代码)
- 可行性研究报告计算机,台式计算机项目可行性研究报告范文.doc
- C++播放wav音乐和音效
- 上传图片报413错误
- 对token(令牌)的理解
- 「JavaSE」- 常用类
- JavaScript进阶(四)
- HDU 2544 最短路(最短路入门)
- 北京理工大学 计算机学院 李侃,吴昊_北京理工大学计算机学院
- 财务内部收益率用计算机怎么算,财务内部收益率EXCEL怎么计算
- 萌新用计算机弹加勒比海盗,我来发个加勒比海盗的技巧吧
- 对加噪音前后的音频信号进行频谱分析
- access如何保存小数点后_条码标签打印软件如何批量制作订单标签
- CSS命名规范 BEM
- 西工大计算机学院软件工程专硕,2021双非上岸西工大软院专硕