【数据结构】并查集
来源:互联网 发布:linux打包tar.gz 编辑:程序博客网 时间:2024/06/09 14:04
上次ACM集训时,有人问我Kruskal,结果并查集他不是很清楚,就比较麻烦了。所以这次顺便写一下并查集。
并查集是一种高效的数据结构。它主要对集合进行查询和合并操作。
并——将两个元素所在的集合合并为一个。
查——查看元素在哪一个集合中,进而查看两个元素是否在同一个集合内。
集——这里的集合,是用一棵树表示的。
我们先来说集合的表示,我们把同一个集合的元素放在同一棵树里,这样它们就会有相同的根节点,代表它们在同一个集合中。至于在元素在树里的次序是无关紧要的,我们只关心它在哪个集合(树)里。
集合A={1,3,5,7,9} 集合B={2,4,6,8,10}
接下来要进行查询操作,即找到该元素所在树的根节点,只需要不断地访问元素的父亲,父亲的父亲,以此类推,所以我们需要一个father数组,来记录树中每个元素的父节点。开始的时候,如果每个元素是独立的,我们应该把每个元素的father设为自己。
father[i]=i;
合并操作就更简单了,找到两个元素所在的树的根节点,将一个根设为另一个根的孩子即可。
合并后的集合A+B
接下来我们看具体实现。为了实现查操作,我们定义函数
int findfather(int x){ if (x==father[x]) return x; else return findfather(father[x]);}很容易理解,如果它的父亲是它自己,那么他就是根节点,返回自己;否则,从它的父亲寻找根节点并返回。这里我们可以加一个优化,叫做路径压缩,因为我们在找根节点的时候,一路问别人,直到找到根节点,那么回来的时候,举手之劳,顺便告诉别人根节点是谁,这样别人下次查询时直接就知道了,这样多好。
我们代码改成
if (x==father[x]) return x; else return father[x]=findfather(father[x]);
这样一来,假设我们查询的是4号点,查询前后的树如图,我们发现多次查询后,树的深度就会变浅。
查询前 查询后
接着看合并操 union_set
bool union_set(int x, int y){ int fx=findfather(x); int fy=findfather(y); if (fx==fy) return false; father[fx]=fy; return true;}
我们看到只需要找到两棵树的根节点,然后把一个的父亲设为另外一个就可以了。但是,我们发现如果遇到特殊情况,不断地合并会出现这样的情况。
退化了的集合树
为了解决这个问题,我们可以设一个rank数组来记录每棵树的深度,在合并时,应让深度小的作为深度大的树的子树,将father[fx]=fy改写为
if(rank[fx]<rank[fy])father[fx]=fy;else if (rank[fx]>rank[fy] )father[fy]=fx;else //深度相同树,大树的深度才会增加{ father[fx]=fy; rank[fy]++; }
注意,rank数组记得初始化。
至此,并查集的结构,操作我们已经解决的差不多了。让我们来看一份完整的代码:
#include<stdio.h>intfather[10000];Intrank[10000];int findfather(int x){ if (father[x]==x) return x; else returnfather[x]=findfather(father[x]); //路径压缩}void union_set(int x, int y){ int fx=findfather(x); int fy=findfather(y); if(rank[fx]<rank[fy])father[fx]=fy; else if(rank[fx]>rank[fy] )father[fy]=fx; else { father[fx]=fy; rank[fy]++; }}int main(){ for (i=1; i<=10000; i++) father[i]=i; for (i=1; i<=10000; i++) rank[i]=1; int n; //n条指令 scanf("%d",&n); for (i=1; i<=n; i++) { int x,y; scanf("%d%d",&x,&y); union_set(x,y); }}
- 数据结构-并查集
- 数据结构-并查集
- 并查集【数据结构】
- 【数据结构】并查集
- 数据结构-并查集
- 数据结构 并查集
- 数据结构 并查集
- 数据结构 -- 并查集
- 数据结构---并查集
- 数据结构---并查集
- 数据结构-并查集
- 数据结构 并查集
- 数据结构-并查集
- [数据结构].并查集
- 并查集 数据结构
- 数据结构-并查集
- 【数据结构】并查集
- 数据结构--并查集
- ios 画图总结
- ASP做网页时的问题记录
- ffmpeg+ffserver搭建流媒体服务器
- 使用ffserver实现转发实时流媒体(摄像头捕获)
- ffmpeg的使用,及发送媒体流的一些简单介绍
- 【数据结构】并查集
- Ubuntu软件图标默认放置文件夹
- Java基础之集合框架(三)--Map、HashMap、TreeMap
- web.py 学习之 helloworld
- 《大话设计模式》读书笔记
- java中的枚举
- C++中访问控制
- paip.输入法编程---输入法ATIaN历史记录
- 【Java】IO操作之使用zip包压缩和解压缩文件