数据结构之并查集:UF-Tree优化并查集——19

并查集的优化

在上一节了解到并查集的快速查询,合并,判断归属组等操作,虽然这些操作都非常方便,但是在数据量较大的情况下,并查集的效率并不算高:

上一节中实现代码中使用的合并方法(merge,API设计中为union),每次合并都需要遍历全部元素的次数,而最少要合并N-1次才能将所有元素合并到同一组,因此我们要对其合并进行优化

为了提升union算法的性能,我们需要重新设计find方法和merge方法的实现,此时我们先需要对我们的之前数据结构中的groups数组的含义进行重新设定。

使用

优化查询分组which_group方法
  1. 我们仍然让groups数组的索引作为结点的元素
  2. groups[i]的值不再是当前结点所在的分组标识,而是当前结点的父结点,根据当前结点的父结点可以找到祖父结点,一直往上找,直到找到它的根结点,根结点则是其真正的分组
    在这里插入图片描述
Python代码实现及测试
class UF_Tree:
    def __init__(self, n):
        self.num_groups = n
        self.groups = [i for i in range(n)]

    def count_groups(self):
        return self.num_groups

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

    def which_group(self, item):
        """Find item's root------>groups[groups[groups[...groups[item]...]]]"""
        while self.groups[item] != item:
            item = self.groups[item]
        return item

    def merge(self, item1, item2):
        if self.in_the_same_group(item1, item2):
            return
        self.groups[self.which_group(item1)] = self.groups[self.which_group(item2)]
        self.num_groups -= 1


if __name__ == '__main__':
    UF = UF_Tree(5)

    print(f"The initial number of groups is {UF.num_groups}")
    print(f"The initial number of 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 number of 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
[1, 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
[1, 2, 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
[1, 2, 3, 4, 4]
Input the to-be-merge element: 

可以寻找到item = 0的源分组为4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于最小生成树问题的算法实现。这里介绍的是使用并查集的思想,具体实现步骤如下: 1. 输入 n,e,表示端点数量和边的数量。 2. 初始化并查集,将每个端点看成一个集合。 3. 输入每条边的信息,包括端点1,端点2和边的权值。 4. 对所有边按照权值从小到大排序。 5. 遍历排好序的边,对于每条边,判断其两个端点是否在同一个集合中。 6. 如果不在同一个集合中,则将它们合并,并将这条边加入生成树中。 7. 最终得到的生成树就是最小生成树,输出生成树中的边的信息和生成树的权值之和即可。 下面是使用并查集求解最小生成树的 Python 代码实现: ```python class UnionFind: def __init__(self, n): self.parent = list(range(n)) self.rank = [0] * n def find(self, i): if self.parent[i] != i: self.parent[i] = self.find(self.parent[i]) return self.parent[i] def union(self, i, j): pi, pj = self.find(i), self.find(j) if pi == pj: return False if self.rank[pi] < self.rank[pj]: pi, pj = pj, pi self.parent[pj] = pi if self.rank[pi] == self.rank[pj]: self.rank[pi] += 1 return True n, e = map(int, input().split()) edges = [] for i in range(e): n1, n2, e1 = map(int, input().split()) edges.append((e1, n1, n2)) edges.sort() uf = UnionFind(n) tree = [] weight = 0 for e1, n1, n2 in edges: if uf.union(n1, n2): tree.append((n1, n2, e1)) weight += e1 print(tree) print(weight) ``` 希望这个算法实现对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值