并查集UFS

2018-07-29  本文已影响0人  钢筋铁骨

简介

并查集(Union Find Set)是一种高级数据结构,主要用于图存储中不同集合的合并与查询问题。并查集这种数据结构在数据存储时,由于使用了路径压缩的方法,使得最终的查询时间复杂度大大降低,变成了O(1)

实现思路

并查集归根结底可以算作是树形结构,主要实现了两个功能,union和find

假设有["A","B","C","D","E","F"]6个节点,其中("A","E"),("B","C"),("C","F")两两关联。那么最终会得到3个集合(D)、(A,E)和(B,C,F)

如下图:

分别对A,B,C,D,E,F标号为1,2,3,4,5,6。因为A,E相连,把A和E的索引(也有叫做父节点的)换成相同的。因为B,C,F相连,把B,C,F的索引换成相同的,如下图:

得到这个结果后,能够知道A,B,C,D,E,F共有3个连通集合,分别是1,2,3。此过程在创建并查集的时候(也可以是首次查找时)实现,存储了这样的数据结构后,在查找F时可以直接找到F属于簇2,而不需要找F的父节点是C,C的父节点是B。

Python代码实现


class UnionFindSet(object):

    parent = []# 存储每个元素的父节点,记作1,2,3,4,5...

    count =0  # 一共有几组,初始化时各元素单独成组

    def __init__(self, origin_set, n):

        self.count = n# 样本数量

        self.partition_count = n# 样本分类数量

        self.origin_items = origin_set# 样本们

        # 初始化的数据结构时,每个元素的父节点都是自己,然后做union

        for i in range(0, n):

              self.parent.append(i)

    def isconnect(self, i, j):

          return self.find(i) == self.find(j)

    def find(self, i):

          p_i = self.origin_items.index(i)

          return self.parent[p_i]

    def find_set(self, cluster):

        result = []

        size = len(self.parent)

        for indexin range(size):

        if self.parent[index] == cluster:

        result.append(self.origin_items[index])

        return result

    def union(self, i, j):

        root_i = self.find(i)

        root_j = self.find(j)

        if root_i == root_j:

            print ("----------%s 和 %s 已经是连通的----------" %(i, j))

            return True

        else:# root_i != root_j:

            self.parent[root_i] = root_j

            self.partition_count -=1

            for xin self.origin_items:

                # 如果父节点相同,压缩路径

                if self.parent[self.origin_items.index(x)] == root_i:

                   self.parent[self.origin_items.index(x)] = root_j

def main():

    sample = ["A","B","C","D","E","F"]

    sample_n = len(sample)

    ufs = UnionFindSet(sample, sample_n)

    print ("初始化并查集parent list: %s" % (",").join(str(x)for xin ufs.parent))

    link = [

        ("A","E"),

        ("B","C"),

        ("C","F")

    ]

    for k in link:

        p = k[0]

        q = k[1]

        ufs.union(p, q)

    print ("建立连接关系: %s和%s " %(p, q))

    print ("最终分类数量: %s" %(ufs.partition_count))

    print ("最终分类:\n %s\n%s" %(sample, ufs.parent))

    item ="A"

    cluster = ufs.find(item)

    print ("%s属于%s" %(item, cluster))


最后在网上找到一张有意思的图,能够清晰的说明并查集是什么。门派的划分!

代码是描绘客观事物存在方式和运动方式的一组计算机符号啊

上一篇下一篇

猜你喜欢

热点阅读