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相关推荐

  1. 并查集(disjoint set)的实现及应用

    这里有一篇十分精彩.生动的 并查集详解 (转): "朋友的朋友就是朋友"⇒ 传递性,建立连通关系 disjoint set,并查集(一种集合),也叫不相交集,同时也是一种树型的数据 ...

  2. 352. Data Stream as Disjoint Intervals

    题目链接: https://leetcode.com/problems/data-stream-as-disjoint-intervals/ Given a data stream input of ...

  3. boost::geometry::disjoint用法的测试程序

    boost::geometry::disjoint用法的测试程序 实现功能 C++实现代码 实现功能 boost::geometry::disjoint用法的测试程序 C++实现代码 #ifndef ...

  4. C++用并查集Disjoint union实现connected component连通分量(附完整源码)

    C++用并查集Disjoint union实现connected component连通分量 C++用并查集Disjoint union实现connected component连通分量完整源码(定义 ...

  5. C++并查集Disjoint Set(附完整源码)

    C++并查集Disjoint Set 并查集Disjoint Set算法的完整源码(定义,实现,main函数测试) 并查集Disjoint Set算法的完整源码(定义,实现,main函数测试) #in ...

  6. C语言实现并查集(Disjoint set或者Union-find set)(附完整源码)

    实现实现并查集 实现并查集(Disjoint set或者Union-find set)的完整源码(定义,实现,main函数测试) 实现并查集(Disjoint set或者Union-find set) ...

  7. 判断2个list中是否有相同的数据(相交)Collections.disjoint

    比较两个集合中是否有相同的元素,发现Collections类下的disjoint方法可以处理 Collections.disjoint() 代码如下: List<Integer> list ...

  8. 图论学习四之Disjoint set union并查集

    分离集合 • 在有的问题中,需要对不相交的集合(disjoint set)进行这样两种操   作: • 检索某元素属于哪个集合 • 合并两个集合 • 此时,我们可以使用并查集维护这两个操作. 并查集的 ...

  9. 数据结构 之 并查集(Disjoint Set)

    一.并查集的概念:     首先,为了引出并查集,先介绍几个概念:     1.等价关系(Equivalent Relation)     自反性.对称性.传递性.     假设a和b存在等价关系.记 ...

最新文章

  1. Leetcode: Maximal Rectangle
  2. 震惊!java中日期格式化的大坑!
  3. 白夜:一文看懂AI项目流程及边缘设备开发
  4. Fragment向ChildFragment传值
  5. 利用计算机绘制地质图的思路和方法,基于平面地质图的三维地质建模方法研究...
  6. Emacs+hideif.el 隐藏预编译代码(或彩色显示预编译代码)
  7. 可行性研究报告计算机,台式计算机项目可行性研究报告范文.doc
  8. C++播放wav音乐和音效
  9. 上传图片报413错误
  10. 对token(令牌)的理解
  11. 「JavaSE」- 常用类
  12. JavaScript进阶(四)
  13. HDU 2544 最短路(最短路入门)
  14. 北京理工大学 计算机学院 李侃,吴昊_北京理工大学计算机学院
  15. 财务内部收益率用计算机怎么算,财务内部收益率EXCEL怎么计算
  16. 萌新用计算机弹加勒比海盗,我来发个加勒比海盗的技巧吧
  17. 对加噪音前后的音频信号进行频谱分析
  18. access如何保存小数点后_条码标签打印软件如何批量制作订单标签
  19. CSS命名规范 BEM
  20. 西工大计算机学院软件工程专硕,2021双非上岸西工大软院专硕

热门文章

  1. 计算机操作系统专题一:多道环境下进程同步与互斥制约关系的学习
  2. 伪造谷歌安全类的钓鱼邮件案例
  3. 租借云服务器 工业信号数据采集,一种工业用物联网云服务平台智能采集方法...
  4. 数据可视化模块---Matplotlib
  5. 【企业管理】企业创造的要素
  6. 关闭页面刷新上层页面的几种方式
  7. 网站的几个性能指标和优化(简易)
  8. Postgresql在CentOS上的安装(脚本在线安装)
  9. Java中使用mysqldump实现mysql数据库备份并将sql文件打成zip压缩包
  10. Express请求处理-静态资源的处理