Weighted Quick Union

Weighted Quick Union即:

在Quick Union的基础上对结点加权(weighted),在parent[i]基础上增加一个size[i].

用来存储该结点(site)的所有子结点数目.(size[i] == number of sites in subtree rooted at i)

具体操作步骤:

仅仅在union() operation改变,在改变parent前,增加一个步骤:

比较两个结点的size,谁更轻谁就在下面,

具体看代码:

 1 class WeightedQuickUnion():
 2     __count = int()     #number of components
 3     __parent = list()   #__parent[i] parent of i
 4     __size = list()     #size[i] number of sites in subtree rooted at i
 5     #Each site is initially in its own component
 6     def __init__(self,N):
 7         self.__count = N
 8         for i in range(0,self.__count):
 9             self.__parent.append(i)
10             self.__size.append(1)
11     #Return the component identifier for the component containing site
12     def find(self,p):
13         self.validate(p)
14         while (p != self.__parent[p]):
15             p = self.__parent[p]
16         return p
17     def connected(self,p,q):
18         return self.find(p) == self.find(q)
19     #Merges the component containig site p with
20     #the component containing site q
21     def union(self,p,q):
22         rootP=self.find(p)
23         rootQ=self.find(q)
24         if (rootP == rootQ):
25             return
26         if (self.__size[rootP] < self.__size[rootQ]):
27             self.__parent[rootP] = rootQ
28             self.__size[rootQ] += self.__size[rootP]
29         else:
30             self.__parent[rootQ] = rootP
31             self.__size[rootP] += self.__size[rootQ]
32         self.__count-=1
33     def validate(self, p):
34         n = len(self.__parent)
35         if (p < 0 or p >= n):
36             raise ValueError("index", p, "is not between 0 and", (n - 1))
37     def traversal(self):
38         for i in self.__parent:
39             print(i,end=' ')
40 WQU = WeightedQuickUnion(8)
41 WQU.union(0,1)
42 WQU.union(2,1)
43 WQU.union(2,4)
44 WQU.union(3,7)
45 print(WQU.connected(0,4))
46 WQU.traversal()

实例同上一文Quick Find一样,

连接0-1-2-4 3-7,并调用connected()方法验证0-4是否连接

最后遍历

输出:

True
0 0 0 3 0 5 6 3 

根据输出可以反应出树形图:

      0    3  5  6

    /  |    |

  1   2  4     7

程序中:union()方法里,把size的比较分为两种情况,小于以及大于+等于.

union(0,1)的时候0是p,1是q,他们的size都是1,所以会执行

1             self.__parent[rootQ] = rootP
2             self.__size[rootP] += self.__size[rootQ]

也就是q(1)会成为p(0)的子节点.

union(3,7)同理.

其它情况由于size不同,会按照程序写的那样,把轻的作重的子节点

原文地址:https://www.cnblogs.com/katachi/p/9565347.html