• 【python刷题】并查集


    什么是并查集?

    这里借用百度百科的一句话:并查集是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题。常常在使用中以森林来表示。假设现在有一个武林大会,包含了少林、峨嵋、武当等门派,通过并查集就可以将每个人归类到自己的门派中。

    代码实现

    class UnionFind:
        def __init__(self):
            self.co = 0  # 用于记录群的个数
            self.parent = []  # 索引是每个节点本身,值是每个节点的父节点
            self.size = []  # 用于记录每个群的节点数目
    
        #
        def find(self, x):
            while self.parent[x] != x:
                # self.parent[x] = self.parent[self.parent[x]]  # 用于路径压缩
                x = self.parent[x]
            return x
    
        def union(self, p, q):
            rootP = self.find(p)
            rootQ = self.find(q)
            if rootP == rootQ:
                return
            # 下面的这个if语句用将节点数少的合并到节点数多的群中
            if self.size[rootP] > self.size[rootQ]:
                self.parent[rootQ] = rootP
                self.size[rootP] += self.size[rootQ]
            else:
                self.parent[rootP] = rootQ
                self.size[rootQ] += self.size[rootP]
            self.co -= 1
    
        # 用于判断p和q之间是否连通,如果两个节点的父节点是相同的,那么就是连通的
        def connected(self, p, q):
            rootP = self.find(p)
            rootQ = self.find(q)
            return rootP == rootQ
    
        # 返回有多少个群
        def count(self):
            return self.co
    
        # 初始化,节点的父节点就是其本身,假设n=10,那么就有10个群,self.parent=[0,1,2,3,4,5,6,7,8,9],self.parent[0]=0表示0节点的父节点是0。每个群的size,也就是包含的节点数目就是1,self.size[0]=1。
        def uf(self, n):
            self.co = n
            self.parent = [0 for _ in range(n)]
            self.size = [0 for _ in range(n)]
            for i in range(n):
                self.parent[i] = i
                self.size[i] = 1
    
    unionF = UnionFind()
    unionF.uf(10)
    print("初始化每个节点的父节点:", unionF.parent)
    print("初始化的群个数:", unionF.count())
    unionF.union(0, 3)  # 0,3建立关系
    unionF.union(3, 7)  # 3,7建立关系
    unionF.union(7, 9)  # 7,9建立关系
    unionF.union(2, 8)  # 2,8建立关系
    print("判断{}与{}之间是否在一个群里面:{}".format(3, 8, unionF.connected(3, 8)))
    print("返回节点{}的父节点{}".format(7, unionF.find(7)))
    print("当前每个节点的父节点:", unionF.parent)
    print("当前群的个数:", unionF.count())
    print("当前每一个群的节点个数:", unionF.size)
    

    结果:

    初始化每个节点的父节点: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    初始化的群个数: 10
    判断3与8之间是否在一个群里面:False
    返回节点7的父节点3
    当前每个节点的父节点: [3, 1, 8, 3, 4, 5, 6, 3, 8, 3]
    当前群的个数: 6
    当前每一个群的节点个数: [1, 1, 1, 4, 1, 1, 1, 1, 2, 1]

    更具体的介绍可以去参考labuladong的算法小抄。

  • 相关阅读:
    [转]使用NLog记录日志到数据库 自定义日志表的数据格式
    [转]使用C#实现长整型向任意编码的转换和逆转换
    解释一下 P/NP/NPComplete/NPHard 等问题
    在C#中创建进度窗体
    [转载] 关于Winform编译中的属性设置
    [转]使用NLog記錄Exception
    SQL Server数据库,在表上建立唯一性索引的一些问题
    DES文件字符加密解密
    线程运行超时处理类
    使用FFmpeg从视频中截图的命令
  • 原文地址:https://www.cnblogs.com/xiximayou/p/14325658.html
Copyright © 2020-2023  润新知