并查集算法 | Union-Find Algorithm

Union-Find Algorithm即并查集算法,常用于解决 动态连通性,判断有向无圈图等问题。

 

根本上讲,Union-Find算法就和他的名字一样是一种对不相交集数据结构执行两个有用操作的算法,不相交集数据结构是跟踪一组元素的数据结构,这些元素被划分为多个不相交(非重叠)子集。两个有用操作分别是:

  • 查找(Find):确定特定元素在哪个子集中。这可用于确定两个元素是否在同一个子集中。
  • 联合(Union):将两个子集连接成一个子集。这里首先我们必须检查两个子集是否属于同一个集合。如果不是,那么我们不能执行联合。

在这篇文章中,我们将讨论不相交集数据结构的应用。该应用是检查给定图形是否包含循环。

们跟踪一维数组中的子集,我们称之为 parent[]。
以下图为例
: 

并查集算法 | Union-Find Algorithm_第1张图片

对于每条边,用边的两个顶点制作子集。如果两个顶点都在同一个子集中,则找到一个循环。

最初,父数组的所有槽都初始化为-1(意味着每个子集中只有一项)。

现在一一处理所有边。
边 0-1:找到顶点 0 和 1 所在的子集。由于它们在不同的子集中,我们采用它们的并集。也就是Union-Find中的Union操作,请将节点 1 作为节点 0 的父节点,反之亦然。  

 边 1-2: 1 在子集 1 中,2 在子集 2 中。所以,取并集。

边 0-2: 0 在子集 2 中,2 也在子集 2 中。因此,包括这条边形成一个循环。
0 的子集为什么与 2 相同? 
0->1->2 // 1 是 0 的父级, 2 是 1 的父级   

下面是Union和Find两个操作的简单实现

并查集算法 | Union-Find Algorithm_第2张图片

请注意

上面的union()find()的实现是最简单的版本,其最坏的时间复杂度是O(n) 。可以使用Union by Rank 或 Height将这些方法改进为 O(Logn) 。 我们将在下一篇文章中讨论改进后的Union-Find算法。

Union-Find算法检查图中是否存在循环代码下载链接:

(包含各种语言:C语言、Python、Java、C++、C#、Javascript等均有示例)

免费​资源下载:Union-Find to detect cycle

你可能感兴趣的:(算法,数据结构,leetcode,图搜索算法)