引言
并查集的核心组成函数——五大函数:
__init__
构建父节点字典,构建父节点大小字典,构建节点数数值字典(非必须)
new_UF
生成新的节点
getfather
得到某一结点的父节点
isconnect
判断两个节点是否联通
merge
合并两个节点
例题1
我们还是一道题目为例子。
这是399题,除法求值。是一道带权值的并查集题目。
并查集算法是说可以将相互连通的节点都归类到一个根节点上。这样可以很快的判断两个触电之间时候属于同一类(是否连通)。
一般的算法包括普通的并查集算法,带权值的quick-union算法,和含有路径压缩的算法。这道题目还一个难点在于定义每条边的权值。这里的每个value
是当前节点相对于父节点的大小。具体的可以参考算法4.
这里直接放上代码。
class Solution:
def __init__(self):
self.fathernode = {
}
self.val = {
}
self.size = {
}
# 初始化节点
def new_UF(self, node):
# 当节点已经存在时
if node in self.fathernode:
return
self.fathernode[node] = node
self.val[node] = 1.0
self.size[node] = 1
# 查询父节点 同时进行值的更新
# 使用递归 同时对路径进行压缩 将每个节点连接到与父节点的关系
def getfather(self, node):
if self.fathernode[node] == node:
return node
# 递归得到父节点
fa = self.getfather(self.fathernode[node])
# 递归的更新当前节点得值 前父节点关系值 * 更新后得父节点值
self.val[node] = self.val[self.fathernode[node]] * self.val[node]
# 将节点的父节点更新为最父节点
self.fathernode[node] = fa
return fa
# 合并两个node 将大的合并到小的 保证根为1.0
def merge(self, node1, node2, value):
node1f = self.getfather(node1)
node2f = self.getfather(node2)
#val代表的是当前节点是直接父节点的多少倍
# 两个节点的根相同时不合并
if node1f == node2f:
return
# 分别计算出到node2上 用于比较根的相对大小
val1 = self.val[node1]
val2 = self.val[node2]
size1 = self.size[node1f]
size2 = self.size[node2f]
val1buf = val2 * value
## 采用加权的并查集quick-union
# 当2的为大树时,将1链接到2上
if size1 < size2