并查集实现(路径压缩)

并查集 Union Find 算法

定义

并查集(Disjoint-Set)是一种可以动态维护若干个不重叠的集合,并支持合并与查询两种操作的一种数据结构。

基本操作

  1. 合并(Union):合并两个集合。
  2. 查询(Find):查询元素所属集合。

具体实现

我们建立一个数组father_dict字典表示一个并查集,father_dict[i]表示i的父节点。并且设置一个size_dict字典,size_dict[i]表示i的后代节点的个数,包括其本身。

初始化:

每一个点都是一个集合,因此自己的父节点就是自己father_dict[i]=i,size_dict[i]=1.

查询:

每一个节点不断寻找自己的父节点,若此时自己的父节点就是自己,那么该点为集合的根结点,返回该点。

合并:

合并两个集合只需要合并两个集合的根结点,size_dict大吃小,为了尽可能的降低树高。

路径压缩:

实际上,我们在查询过程中只关心根结点是什么,并不关心这棵树的形态(有一些题除外)。因此我们可以在查询操作的时候将访问过的每个点都指向树根,这样的方法叫做路径压缩,单次操作复杂度为O(logN)。

路径压缩

具体实现:

python 复制代码
    def Find(self, x):
        root = self.father_dict[x]
        # 路径压缩
        while root != self.father_dict[root]:
            root = self.father_dict[root]
        while x != root:
            x, self.father_dict[x] = self.father_dict[x], root
        return root

防止树的退化

python 复制代码
        if self.size_dict[x_father] > self.size_dict[y_father]:
            self.father_dict[y_father] = x_father
            self.size_dict[x_father] += self.size_dict[y_father]
        else:
            self.father_dict[x_father] = y_father
            self.size_dict[y_father] += self.size_dict[x_father]

具体实现代码

python 复制代码
class UnionFindSet:
    def __init__(self, n):
        self.father_dict = {}
        self.size_dict = {}
        for i in range(n):
            self.father_dict[i] = i
            self.size_dict[i] = 1

    def Union(self, x, y):
        x_father = self.Find(x)
        y_father = self.Find(y)
        if x_father == y_father:
            return
        if self.size_dict[x_father] > self.size_dict[y_father]:
            self.father_dict[y_father] = x_father
            self.size_dict[x_father] += self.size_dict[y_father]
        else:
            self.father_dict[x_father] = y_father
            self.size_dict[y_father] += self.size_dict[x_father]

    def Find(self, x):
        root = self.father_dict[x]
        # 路径压缩
        while root != self.father_dict[root]:
            root = self.father_dict[root]
        while x != root:
            x, self.father_dict[x] = self.father_dict[x], root
        return root
相关推荐
祁同伟.41 分钟前
【C++】多态
开发语言·c++
朱嘉鼎2 小时前
C语言之可变参函数
c语言·开发语言
yanxing.D2 小时前
OpenCV轻松入门_面向python(第六章 阈值处理)
人工智能·python·opencv·计算机视觉
JJJJ_iii3 小时前
【机器学习01】监督学习、无监督学习、线性回归、代价函数
人工智能·笔记·python·学习·机器学习·jupyter·线性回归
Han.miracle4 小时前
数据结构——二叉树的从前序与中序遍历序列构造二叉树
java·数据结构·学习·算法·leetcode
北冥湖畔的燕雀5 小时前
C++泛型编程(函数模板以及类模板)
开发语言·c++
Python图像识别6 小时前
71_基于深度学习的布料瑕疵检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
python·深度学习·yolo
mit6.8246 小时前
前后缀分解
算法
QX_hao6 小时前
【Go】--map和struct数据类型
开发语言·后端·golang
你好,我叫C小白6 小时前
C语言 循环结构(1)
c语言·开发语言·算法·while·do...while