数据结构之并查集:并查集的介绍与Python代码实现——18

并查集(Union-find)是一种高效的数据结构,用于处理元素的集合操作,如添加、合并及查询元素是否同属一组。本文深入讲解并查集的原理、结构及Python实现,展示其在Kruskal算法中寻找最小生成树的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

并查集的介绍

  • 并查集(Union-find)数据结构也称作合并查找集(Merge-find set)或者不相交集数据结构(disjoint-set data structure),它是一种记录了由一个或多个元素组成的不连续的分组的集合。并查集提供常数量的复杂度来添加、合并以及确定两个元素是否属于同一个集合。
  • 并查集除了能够实现这些快速便利的操作,它在Krukal算法中寻找最小生成树的图也起着关键的作用
    在这里插入图片描述
    并查集结构
    并查集是一种树形数据结构,但是它和二叉树、红黑树、B树不同,它对树形结构的要求十分简单:
    1. 同一个数据组中的元素对应在同一颗树(判断两个元素是否在同一颗树时,可以判断根结点是否相同)
    2. 同一数据组中的每一个元素对应树中的一个结点
    3. 不同数据组之间不存在任何相关的联系,可以看做多个数据组成一个森林(合并数据组时,只需要将一棵树的根结点指向另一颗树的根结点即可)
    4. 树中的结点不存在硬性的顺序/父子关系
并查集的功能实现
方法设计
  1. self.groups 是一个列表,其索引代表传入的元素的值,其元素代表传入元素所在分组
  2. count_groups() 返回并查集中组的数量
  3. which_group(item) 判断传入的元素item属于哪一个群组
  4. in_the_same_group(item1, item2) 判断传入的两个元素是否在同一个分组
  5. merge(item1, item2) 将两个元素各自所在的分组合并到一个组,合并后的分组为后者所在的组
    在这里插入图片描述
Python代码实现
class UnionFind:
    def __init__(self, n):
        self.num_groups = n
        self.groups = [i for i in range(n)]  # Let the indices be the elements, and the elements be the group numbers

    def count_groups(self):
        return self.num_groups

    def which_group(self, item):
        """The indices are items, the elements are group numbers"""
        return self.groups[item]

    def in_the_same_group(self, item1, item2):
        return self.which_group(item1) == self.which_group(item2)

    def merge(self, item1, item2):
        group1 = self.which_group(item1)
        group2 = self.which_group(item2)
        if group1 == group2:
            return
        for i in range(len(self.groups)):
            if self.groups[i] == group1:
                self.groups[i] = group2
        self.num_groups -= 1
代码测试
if __name__ == '__main__':
    UF = UnionFind(5)

    print(f"The initial number of groups is {UF.num_groups}")
    print(f"The initial groups is {UF.groups}")

    while True:
        p = int(input(f'Input the to-be-merge element: '))
        q = int(input(f"Merge to the target element's group: "))

        if UF.in_the_same_group(p, q):
            print(f"They are already in the same group")
            continue
        UF.merge(p, q)
        print(f"The number of groups now is {UF.count_groups()}")
        print(UF.groups)
测试结果
The initial number of groups is 5
The initial groups is [0, 1, 2, 3, 4]
Input the to-be-merge element: 0
Merge to the target element's group: 1
The number of groups now is 4
[1, 1, 2, 3, 4]
Input the to-be-merge element: 1
Merge to the target element's group: 2
The number of groups now is 3
[2, 2, 2, 3, 4]
Input the to-be-merge element: 2
Merge to the target element's group: 3
The number of groups now is 2
[3, 3, 3, 3, 4]
Input the to-be-merge element: 3
Merge to the target element's group: 4
The number of groups now is 1
[4, 4, 4, 4, 4]
Input the to-be-merge element: 

最少需要n-1 = 4 次合并,就可以将所有元素都合并到一个分组到一个组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值