并查集初探(一) 核心代码

来源:互联网 发布:怎么用手机在知乎提问 编辑:程序博客网 时间:2024/06/06 01:56

在本文中,我们将并查集的基本操作封装为一个,以便后面研究并查集的相关问题。


并查集的基本概念

在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1~3秒)内计算出试题需要的结果,只能用并查集来描述。

(以上文字来源于百度百科)


并查集的储存

简单的并查集只需要储存一个数组即可。我将这个数组描述为father。father[v]表示index为v的元素所对应的父节点。

并查集的实质可以理解为一个用父节点数组储存的森林


并查集的基本操作

基本操作有两种,并和查。

Union,也称并操作,主要是将两个元素所在的集合合并。这种操作的实现方法很容易想到,由于并查集是基于父节点数组储存的,所以我们只需要找到对应的两个元素的根节点,将其中任意一个设置为另一个的根节点即可。需要注意的是,要想合并,就必须用到查操作。

Find,也称查操作,主要是查找一个元素所在的集合根。查找集合根的方法非常简单,如果当前节点不是根节点,就推进到它的根节点然后再次判断,直到找到一个根节点为止。这里需要注意的是,这种Find算法需要较高的时间复杂度,可能为O(n)。事实上,我们可以思考使用记忆化搜索里面的一个基本思想。因此,我们容易想到一种加快查操作速度的方法:路径压缩


路径压缩原理

因为并查集只是元素与集合的从属关系,所以我们并不需要保留并查集原始的树结构。对于并查集森林中的每棵树,我们只需要保留一个深度为2的树即可。如何使用路径压缩?这个操作在查操作内进行修改。(以上参考代码已经使用了路径压缩)。我们找到根节点以后,从原本Find函数输入的元素开始,沿着之前Find的路径,不断将路径上每一个元素的father都设为根节点。这样,如果要强制将原始创建的并查集树压缩,只需要将每一个叶子结点进行一次Find即可。


本节内容到此为止。下一节中,会对并查集解决实际问题进行描述。

0 0
原创粉丝点击