博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并查集入门
阅读量:6364 次
发布时间:2019-06-23

本文共 1025 字,大约阅读时间需要 3 分钟。

并查集的结构:

并查集用树型(非二叉树)结构实现,每个元素对应一个节点,每个组对应一棵树。

并查集是一种不相交集(Disjoint Sets)ADT,常常在使用中以森林来表示,用来管理元素的分组情况。,进行快速规整。可以以高效的进行:

1)Find,查询元素a和b是否属于同一个组

当且仅当两个元素处于同一个集合中时,Find返回相同的名字,即本操作可转换为寻找两个元素的最久远祖先是否相同,即当且仅当a和b在同一个集合中Find(a)==Find(b)。可以采用递归实现沿着树向上走来找到两棵树的根进行比较。

2)Union,合并元素a和b所在的组

设置一个数组Father[x],表示x的“父亲”的编号。那么,合并两个不相交集合的方法就是,找到其中一个树形集合的根节点,将另外一个树形集合的根节点指向它

并查集的优化方法:

1)路径压缩

寻找根节点时,我们一般采用递归查找,但是当元素很多亦或是整棵树变为一条链时,每次Find操作都是O(n)的复杂度。通过路径压缩可以使得并查集变得更加高效,对于每个查询的甚至是经过的节点节点,一旦经过Find找到根节点后,就直接把连向父亲的边直接改为连向根节点,这样以后再次Find时复杂度就变成O(1)了。

2)按秩合并

在树形数据结构中,如果发生了退化的情况,那么并查集的复杂度便会变得很高,为了防止退化的发生,在合并之前记录下每棵树的高度(Rank),合并时如果Rank不同由Rank小的向Rank大的连边。

该算法是动态的(dynamic),因为在算法执行的过程中集合可以通过Union运算发生改变

该算法是在线的(on-line),执行Find时,必须给出答案才能继续进行

常见的应用:求无向图的连通分量个数,最近公共祖先(LCA),实现Kruskal算法求最小生成树等。

代码实现:

int father[MAX_N];int Rank[MAX_N];void init(){    for(int i=0;i

时间复杂度:

O(n*α(n))

其中α(x),对于x=宇宙中原子数之和,α是阿柯曼函数的一个反函数,增长极慢,在可以想象的n的范围内α(x)不超过5,故可视为常数。事实上,路经压缩后的并查集的复杂度是一个很小的常数。

Tarjan的文章里证明了这个复杂度,感兴趣的可以看一下

文章:

转载于:https://www.cnblogs.com/gfvod/p/5548309.html

你可能感兴趣的文章
测试界和学术界应该架起桥梁
查看>>
大隐隐于市,你身边的那些安全隐患你都知道么?
查看>>
这个物联网处理器号称全世界体型最小
查看>>
Decorator模式及其他相似的模式
查看>>
物联网市场迅猛发展 “中国芯”如何把握机会?
查看>>
aws 上使用elb 的多域名问题
查看>>
从 MyEclipse 到 IntelliJ IDEA
查看>>
环球花木网的目标就是致力于打造成为“园林相关行业的专业性门户网站
查看>>
《编写高质量代码:改善c程序代码的125个建议》—— 建议14-1:尽量避免对未知的有符号数执行位操作...
查看>>
《C语言编程魔法书:基于C11标准》——2.2 整数在计算机中的表示
查看>>
全球程序员编程水平排行榜TOP50,中国排名第一
查看>>
HDFS 进化,Hadoop 即将拥抱对象存储?
查看>>
Edge 浏览器奇葩 bug:“123456”打印成“114447”
查看>>
Sirius —— 开源版的 Siri ,由 Google 支持
查看>>
《OpenGL ES应用开发实践指南:Android卷》—— 2.7 小结
查看>>
《Windows Server 2012活动目录管理实践》——第 2 章 部署第一台域控制器2.1 案例任务...
查看>>
Java Date Time 教程-时间测量
查看>>
Selector.wakeup实现注记
查看>>
《Java EE 7精粹》—— 第1章 Java EE 1.1 简介
查看>>
《Exchange Server 2013 SP1管理实践》——导读
查看>>