数据结构 之 并查集
并查集是一种树型的数据结构,其保持着用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。
有一个联合-查找算法(union-find algorithm)定义了两个操作用于此数据结构:
- Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。
- Union:将两个子集合并成同一个集合。
![](/assets/blank.gif)
![](https://code.csdn.net/assets/CODE_ico.png)
- int parent[100];
- //构造一个初始并查集,s是集合元素的个数,此时初始化了s个集合,每一个集合都只有一个元素
- //数组的范围为parent[0]~parent[s-1]
- //初始的时候,数组元素的值都是 -1,表示此时都是根结点。
- void ufset(int s)
- {
- int si=s;
- for(int i=0;i<si;i++)
- parent[i]=-1;
- }
二、合并Union
![](https://code.csdn.net/assets/CODE_ico.png)
- //集合的合并
- //让root2的父指针指向root1即可实现两个集合的合并
- void Union(int root2,int root1)
- {
- parent[root1]+=parent[root2];
- parent[root2]=root1;
- }
举个例子:初始化10个元素(如上图所示),进行下面的合并过程:
![](https://code.csdn.net/assets/CODE_ico.png)
- ufset(10); //初始化10个元素
- Union(6,0);
- Union(7,0);
- Union(8,0);
- Union(4,1);
- Union(9,1);
- Union(3,2);
- Union(5,2);
合并之后的结果:
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](https://code.csdn.net/assets/CODE_ico.png)
- //使用加权规则得到改进的Union操作
- void WeightUnion(int root2,int root1)
- {
- int r2=Find(root2); //r2和r1是root2和root1的父结点
- int r1=Find(root1);
- int temp;
- if(r1!=r2)
- {
- temp=parent[r1]+parent[r2];
- if(parent[r1]<parent[r2]){parent[r1]=temp;parent[r2]=r1;} //以r2根的树结点多
- else {parent[r1]=r2;parent[r2]=temp;}
- }
- }
![](https://code.csdn.net/assets/CODE_ico.png)
- //使用加权规则得到改进的Union操作
- void WeightUnion(int root2,int root1)
- {
- int r2=Find(root2); //r2和r1是root2和root1的父结点
- int r1=Find(root1);
- int temp;
- temp=parent[r1]+parent[r2];
- if(parent[r1]<=parent[r2])
- //注意:parent[r1] 和 parent[r2] 都是负数,所以小者其绝对值大,那么拥有的结点数就多
- //这里就说明 r1为根的树结点 不少于 r2为根的树结点
- {
- parent[r1]=temp; //以r1为根
- parent[r2]=r1;
- }
- else
- {
- parent[r1]=r2;
- parent[r2]=temp;
- }
- }
![](https://code.csdn.net/assets/CODE_ico.png)
- //查找元素x所在集合
- //从x开始,沿父指针链一直向上,直到向上,直到达到一个父指针域为负值的结点位置
- int Find(int x) //迭代查找方式
- {
- while(parent[x]>=0) x=parent[x];
- return x;
- }
- /*
- int find_1(int x) //递归查找方式
- {
- if(parent[x]<0) return x; //x是根时,直接返回x
- else return find_1(parent[x]); //否则,递归找x的父的根
- }
- */
进一步优化,在查找过程中可以采用折叠规则压缩路径。
![](/assets/blank.gif)
![](https://code.csdn.net/assets/CODE_ico.png)
- //折叠规则压缩路径法
- //包含元素i的树中搜索根,并将从元素i到根的路径上的所有结点都变成根的结点
- int collapsingfind(int i)
- {
- int j;
- for(j=i;parent[j]>=0;j=parent[j]); //搜索j的根
- while(i!=j) //向上逐次压缩
- {
- int temp=parent[i];
- parent[i]=j;
- i=temp;
- }
- return j; //返回根
- }
![](https://code.csdn.net/assets/CODE_ico.png)
- #include <iostream>
- using namespace std;
- int parent[100];
- //构造一个初始并查集,s是集合元素的个数,此时初始化了s个集合,每一个集合都只有一个元素
- //数组的范围为parent[0]~parent[s-1]
- //初始的时候,数组元素的值都是 -1,表示此时都是根结点。
- void ufset(int s)
- {
- int si=s;
- for(int i=0;i<si;i++)
- parent[i]=-1;
- }
- //查找元素x所在集合
- //从x开始,沿父指针链一直向上,直到向上,直到达到一个父指针域为负值的结点位置
- int Find(int x) //迭代查找方式
- {
- while(parent[x]>=0) x=parent[x];
- return x;
- }
- /*
- int find_1(int x) //递归查找方式
- {
- if(parent[x]<0) return x; //x是根时,直接返回x
- else return find_1(parent[x]); //否则,递归找x的父的根
- }
- */
- //折叠规则压缩路径法
- //包含元素i的树中搜索根,并将从元素i到根的路径上的所有结点都变成根的结点
- int collapsingfind(int i)
- {
- int j;
- for(j=i;parent[j]>=0;j=parent[j]); //搜索j的根
- while(i!=j) //向上逐次压缩
- {
- int temp=parent[i];
- parent[i]=j;
- i=temp;
- }
- return j; //返回根
- }
- //集合的合并
- //让root2的父指针指向root1即可实现两个集合的合并
- void Union(int root2,int root1)
- {
- parent[root1]+=parent[root2];
- parent[root2]=root1;
- }
- //使用加权规则得到改进的Union操作
- void WeightUnion(int root2,int root1)
- {
- int r2=Find(root2); //r2和r1是root2和root1的父结点
- int r1=Find(root1);
- int temp;
- if(r1!=r2)
- {
- temp=parent[r1]+parent[r2];
- if(parent[r1]<parent[r2]){parent[r1]=temp;parent[r2]=r1;} //以r2根的树结点多
- else {parent[r1]=r2;parent[r2]=temp;}
- }
- }
- int main()
- {
- ufset(10); //初始化10个元素
- Union(6,0);
- Union(7,0);
- Union(8,0);
- Union(4,1);
- Union(9,1);
- Union(3,2);
- Union(5,2);
- for(int i=0;i<10;i++) cout<<parent[i]<<" ";
- return 0;
- }
数据结构 之 并查集相关推荐
- 数据结构-PHP 并查集(Union Find)
文章目录 数据结构-PHP 并查集(Union Find) 1.并查集示意图 2.并查集合并 3.并查集简单的代码示例 3.1 PHP代码定义 3.2 输出演示 数据结构-PHP 并查集(Union ...
- 数据结构之并查集Union-Find Sets
1. 概述 并查集(Disjoint set或者Union-find set)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题. 2. 基本操作 并查集 ...
- 数据结构之并查集:并查集的介绍与Python代码实现——18
并查集的介绍 并查集(Union-find)数据结构也称作合并查找集(Merge-find set)或者不相交集数据结构(disjoint-set data structure),它是一种记录了由一个 ...
- 数据结构 之 并查集(Disjoint Set)
一.并查集的概念: 首先,为了引出并查集,先介绍几个概念: 1.等价关系(Equivalent Relation) 自反性.对称性.传递性. 假设a和b存在等价关系.记 ...
- 数据结构 7并查集(DISJOINT SET)
并查集(The disjoint set ADT) 等价关系 Relation R:若对于每一对元素(a,b),a,b∈S,aRb或者为true或者为false,则称集合S上定义关系R.如果aRb为t ...
- [重修数据结构0x03]并查集、堆、优先队列(2021.8.11)
前言 在做遍历的题目的时候,发现掌握一些特殊的数据结构和技巧有时对解决题目有着决定性的作用,不可不学.因此特地拿出来两天学习一下并查集.堆.优先队列.以后有更多思考和感悟再加补充吧.内容来自算法笔记, ...
- 高阶数据结构(1):并查集 与 图
"Head in the clouds" 一.并查集 (1)认识并查集? 在一些问题中需要将n个不同的元素划分成 一些不想交的集合. 开始时,每个元素自成一个单元素集合,然后按一定 ...
- 【高级数据结构】并查集
目录 A.AcWing 1250. 格子游戏 B.AcWing 1252. 搭配购买 C.AcWing 237. 程序自动分析 D.AcWing 239. 奇偶游戏 E.AcWing 238. 银河英 ...
- 0x41.数据结构进阶 - 并查集
目录 一.路径压缩与按秩合并 1.AcWing 237. 程序自动分析(NOIP2015) 二.边带权并查集 1.AcWing 238. 银河英雄传说(边带权并查集模板) 2.AcWing 239. ...
最新文章
- 头条三面:toString()、String.valueOf、(String)强转,有啥区别?
- Hadoop的TextInputFormat的作用,如何自定义实现的
- mysql通过函数完成10的阶乘_请使用函数的递归调用编写求阶乘的函数,并计算1!+2!+3!+4!+5!...
- select事件有哪些_Android 深入底层:Linux事件管理机制 epoll
- GDB中应该知道的几个调试方法-转
- Selenium常见异常分析及解决方案
- 【贪心School】机器学习课程笔记
- String、StringBuiler、StringBuffer的区别
- jQuery特效:实现抽奖
- 为什么32.768kHz的晶振封装这么另类?
- wgs84坐标系经纬度投影_南方cass坐标转经纬度_坐标转经纬度软件
- 互联网产品经理核心素质能力模型
- java解密加密MD5
- 阿里云远程桌面连接不到的问题
- 用数据说话,Python就业前景分析
- LZY碎大石(YYOJ)(优先队列
- 新绝代双骄三常见问题解答(不同于网上那片)
- 【*夜深了,无心睡眠*】
- 小鱼征服鼠标宏—第一天—获取鼠标x,y坐标实时动态
- 物联网是如何让世界变得更好
热门文章
- 【MATLAB】数据类型 ( 矩阵 | 随机数函数 | 生成矩阵 )
- 【OpenGL】十一、OpenGL 绘制多个点 ( 绘制单个点 | 绘制多个点 )
- 【计算理论】可判定性 ( 可判定性总结 )
- POJ 3356 水LCS
- python成长之路——第四天
- Cocos2d-x 3.0游戏开发之虚拟机IOS环境:匹配才是好,莫要随便升级软件
- Microservice Anti-patterns
- 关于java中的不可变类(转)
- 【转】每天一个linux命令(39):grep 命令
- [转载]明天的数字营销分析工具2