并查集的应用

接前面

连通图的最小生成树里面的克鲁斯卡尔算法应用并查集后简洁明了。

回顾

最小生成树就是把顶点边(数据结构)表示的生活中的连通图,改成树型数据结构表示的形式。并查集这种数据结构也可以表示树。有多的对比就选最好的。

普里姆算法

文章里先讲了普里姆算法。它是指定一个顶点开始生成树。还使用MST性质:最小权w的pu(堆顶的uv)一定在U和V-U构成的所有顶点的最小生成树中。依次找最小的边。比较起来Python的堆模块很简洁,只十行以内的代码。比书上的少多了,但也是帮助理解学习书上的内容。

克鲁斯卡尔算法

相比之下,克鲁斯卡尔算法就站在一个更高的高度,不用指定开始顶点。当然也是依据MST性质,生成的是同样的最小生成树。书上只给了算法的框架没有代码。前面文章也用并查集实现了,今天再复习一下并查集。

UnionFind

用指定长的列表学习模拟并查集的实现和操作。

class UnionFind:
    def __init__(self, n):
        self.up = list(range(n)) # 0 to n - 1 are the elements
        self.rank = [0] * n

    def find(self, x):
        assert x < len(self.up)
        if self.up[x] == x:
            return x
        else:
            self.up[x] = self.find(self.up[x]) #Recursive call until x is found
            return self.up[x]
    def union(self, x, y):
        repr_x = self.find(x)
        repr_y = self.find(y)
        if repr_x == repr_y:
            return False #already in a same union
        if self.rank[repr_x] == self.rank[repr_y]:
            self.rank[repr_x] += 1
            self.up[repr_y] = repr_x
        elif self.rank[repr_x] > self.rank[repr_y]:
            self.up[repr_y] = repr_x
        else:
            self.up[repr_x] = repr_y
        return True

验证

'''
>>> a=UnionFind(10)
>>> a.find(5)
5
>>> a.find(9)
9
>>> a.union(5,9)
True
>>> a.find(4)
4
>>> a.find(5)
5
>>> a.find(9)
5
>>> print(a.rank)
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
>>> print(a.up)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 5]    
>>> a.find(-1)
999
-1也是可以的,当成下标了。
'''
并查集的应用验证

从验证来看,查找和合并的是下标,5、8、9都合到7,7的rank是1层。2、4合并后下标4的值改成了2,再与8合并后,7的rank就变成两层了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值