并查集其实是一个数组,数组的元素是下标的父节点。这里可以考虑路径压缩,使每次查找时将元素直接指向祖先节点,这样可以提高查找效率。
并查集主要涉及查找和合并两个函数操作。
type father []int
// 初始化并查集
func Constructor(n int) []int {
f := make(father, n)
//首先初始化每个节点的祖先都是自己,也就相当于每个元素各自为一个集合
for i := 0; i < n; i++ {
f[i] = i
}
return f
}
// 查找操作
func (f father) find(i int) int {
if f[i] != i {
//这里进行了路径压缩
f[i] = f.find(f[i])
}
return f[i]
}
// 合并操作,输入两个元素下标,将它们合并为一个集合
func (f father) union(i, j int) {
rootI := f.find(i)
rootJ := f.find(j)
//说明它们本来就是一个集合中的
if rootI == rootJ {
return
}
//将i所在集合的祖先节点指向j的祖先,也就是将i所在集合合并到j所在的集合中,合并后的集合祖先为j的祖先
f[rootI] = rootJ
}