并查集,顾名思义是一种用来处理集合间合并与查询的数据结构,主要包括如下操作:(1)查询:查找元素所在的集合即根节点。(2)合并:将两个元素所在的集合合并为一个集合。并查集主要用于图论问题,例如判断一个图是否连通图、某两个点是否在图中的同一连通子图中等。算法需要以下几个子过程:(1)对每一个节点u建立一个集合MakeSet(u),集合的元素只有u自己,表示最开始时u与其他节点没有路径。(2)给出一个代表路径的二元关系R(u,v),首先通过查询功能Find()分别找到u和v所在集合的根节点,利用Find(a)==Find(b)判断u和v是否在同一集合中,如果不是就使用合并功能Merge(a, b)将u所在的集合和v所在的集合合并。重复执行该步。(3)处理完所有二元关系后,每个集合便代表一个连通子图。接下来考虑选择何种数据结构实现并查集,使算法的效率更高。(1)单链表形式同一集合中的节点串成一条链表,该链表的第一个节点所谓集合的根节点,具体的节点结构如下:
(2)树形结构利用有根树来表示集合,每棵树表示一个集合,树根即集合的根节点。
注意:(1)上述树形结构的并查集也可以使用数组+索引的形式实现,在这里不再重复。(2)树结构下算法的耗时主要体现在Find函数上,可以通过路径压缩进行优化。例如,在对节点1执行Finds函数时,可以顺便将节点1、2、3的父节点改为节点4,以后再对节点1、2、3调用Find函数时就只需要O(1)的时间。