现在的位置: 首页 > 综合 > 正文

python 实现并查集源代码

2013年11月17日 ⁄ 综合 ⁄ 共 1136字 ⁄ 字号 评论关闭

问题描述:


这是典型的并查集的应用,并查集的概念详见:http://www.doc88.com/p-375363060663.html

#coding:utf-8
#py2.7

class unionfind:
    def __init__(self, groups):
        self.groups=groups
        self.items=[]
        for g in groups:
            self.items+=list(g)
        self.items=set(self.items)
        self.parent={}
        self.rootdict={} #记住每个root下节点的数量
        for item in self.items:
            self.rootdict[item]=1
            self.parent[item]=item

    def union(self, r1, r2):
        rr1=self.findroot(r1)
        rr2=self.findroot(r2)
        cr1=self.rootdict[rr1]
        cr2=self.rootdict[rr2]
        if cr1>=cr2:  #将节点数量较小的树归并给节点数更大的树
            self.parent[rr2]=rr1
            self.rootdict.pop(rr2)
            self.rootdict[rr1]=cr1+cr2
        else:
            self.parent[rr1]=rr2
            self.rootdict.pop(rr1)
            self.rootdict[rr2]=cr1+cr2

    def findroot(self, r):
        """
        可以通过压缩路径来优化算法,即遍历路径上的每个节点直接指向根节点
        """
        if r in self.rootdict.keys():
            return r
        else:
            return self.findroot(self.parent[r])

    def createtree(self):
        for g in self.groups:
            if len(g)< 2:
                continue
            else:
                for i in range(0, len(g)-1):
                    if self.findroot(g[i]) != self.findroot(g[i+1]): #如果处于同一个集合的节点有不同的根节点,归并之
                        self.union(g[i], g[i+1])

    def printree(self):
        rs={}
        for item in self.items:
            root=self.findroot(item)
            rs.setdefault(root,[])
            rs[root]+=[item]
        for key in rs.keys():
            print rs[key],


u=unionfind([('a','b','c'),('b','d'),('e','f'),('g'),('d','h')])
u.createtree()
u.printree()

抱歉!评论已关闭.