python----并查集,,Quick Find


Quick Find

# -*- coding: utf-8 -*-class QuickFind(object):    id = []    cnt = 0  # the number of the sets    def __init__(self, n):        self.cnt = n        for i in range(0, n):            self.id.append(i)    def connected(self, p, q):        return self.find(p) == self.find(q)    def find(self,p):        return self.id[p]    def union(self,p,q):        id_p = self.find(p)        if not self.connected(p,q):            for i in range(0,len(self.id)):                if self.id[i] == id_p:                    self.id[i] = self.id[q]  #combine            self.cnt -= 1qf = QuickFind(10)print("initial id list is %s" % (‘,‘).join(str(x) for x in qf.id))list = [        (4,3),        (3,8),        (6,5),        (9,4),        (2,1),        (8,9),        (5,0),        (7,2),        (6,1),        (1,0),        (6,7)        ]for edge in list :    p = edge[0]    q = edge[1]    qf.union(p,q)    print("%d and %d is connected? %s"%(p,q,str(qf.connected(p,q))))print("final id list is %s" %(",").join(str(x) for x in qf.id))print("count of sets is : %d" % qf.cnt)

connect更新的时候需要遍历,可以借用树结构来减小时间复杂度。

# -*- coding: utf-8 -*-class QuickUnion(object):    id = []    cnt = 0  # the number of the sets    def __init__(self, n):        self.cnt = n        for i in range(0, n):            self.id.append(i)    def connected(self, p, q):        return self.find(p) == self.find(q)    def find(self,x):        while(x != self.id[x]):            x = self.id[x]        return x    def union(self,p,q):        root_p = self.find(p)        root_q = self.find(q)        if not self.connected(p,q):            self.id[root_p] = root_q            self.cnt -= 1    qu = QuickUnion(10)print("initial id list is %s" % (‘,‘).join(str(x) for x in qf.id))list = [        (4,3),        (3,8),        (6,5),        (9,4),        (2,1),        (8,9),        (5,0),        (7,2),        (6,1),        (1,0),        (6,7)        ]for edge in list :    p = edge[0]    q = edge[1]    qu.union(p,q)    print("%d and %d is connected? %s"%(p,q,str(qu.connected(p,q))))print("final id list is %s" %(",").join(str(x) for x in qu.id))print("count of sets is : %d" % qu.cnt)

Weighted Quick Union

Quick Union 可能会退化成链,导致性能下降,可以通过Weighted Quick Union尽量平衡树的高度,从而提升性能。

# -*- coding: utf-8 -*-class WeightedQuickUnion(object):    id = []    cnt = 0  # the number of the sets    sz = []    def __init__(self, n):        self.cnt = n        for i in range(0, n):            self.id.append(i)            self.sz.append(1)    def connected(self, p, q):        return self.find(p) == self.find(q)    def find(self,x):        while(x != self.id[x]):            x = self.id[x]        return x    def union(self,p,q):        root_p = self.find(p)        root_q = self.find(q)        if not self.connected(p,q):            if self.sz[q] > self.sz[p]:    #保证小树连大树,若大树连小树可能退化成链                self.id[root_p] = root_q                self.cnt -= 1                self.sz[q] += self.sz[p]            else :                self.id[root_q] = root_p                self.cnt -= 1                self.sz[p] += self.sz[q]wqu = WeightedQuickUnion(10)print("initial id list is %s" % (‘,‘).join(str(x) for x in wqu.id))list = [        (4,3),        (3,8),        (6,5),        (9,4),        (2,1),        (8,9),        (5,0),        (7,2),        (6,1),        (1,0),        (6,7)        ]for edge in list :    p = edge[0]    q = edge[1]    wqu.union(p,q)    print("%d and %d is connected? %s"%(p,q,str(wqu.connected(p,q))))print("final id list is %s" %(",").join(str(x) for x in wqu.id))print("count of components is : %d" % wqu.cnt)

可通过压缩查找进一步提升性能,类似树桩。

参考:http://www.cnblogs.com/learnbydoing/p/6896472.html?utm_source=itdadao&utm_medium=referral

python----并查集

评论关闭