并查集
一共两个函数
find() 查找根节点
union() 合并两个集合
根据树的高度合并两集合
定义一个rank[]数组,存储两个树的高度,比如rank[xroot] = 3
如果rank[xRoot] > rank{yRoot]的时候,就是x那个树比y那个树要高,所以合并的时候将y那个树的根节点给连接到x那个树的根节点下面。
如果rank[xRoot] = rank[yRoot] 的时候,这个时候树就要高一层了,rank[xRoot] ++
代码
func initParent(rank []int,parent []int,length int){ for i := 0 ; i < length ; i ++{ parent[i] = i rank[i] = 0 } } func findRoot(x int,parent []int)int { xRoot := x if parent[x] == xRoot{ return xRoot }else{ //递归查找,每次都更新节点的最终根节点,使得树的深度为2层 xRoot = findRoot(parent[x], parent) parent[x] = xRoot } return xRoot } //按照树高度归并 func union2(x int,y int,parent []int,rank []int) bool{ xRoot := findRoot(x,parent) yRoot := findRoot(y,parent) //如果两个节点已经在一个树了,说明再加上这个边就有环了 if xRoot == yRoot{ return false } //如果x树高,就把y所在的那个树放到x那个树的根下面 if rank[xRoot] > rank[yRoot]{ parent[yRoot] = xRoot }else{ parent[xRoot] = yRoot //如果两个树一样高,这时候rank就高度++了 if rank[xRoot] == rank[yRoot] { rank[yRoot] ++ } } return true } func main() { e := [][]int { {1,2},{2,3},{2,4},{3,5},{4,5}, } parent := make([]int,6) rank := make([]int,6) initParent(rank,parent,6) for i:= 0;i < len(e) ;i++ { result := union2(e[i][0], e[i][1], parent, rank) if !result{ fmt.Print("cycles found.") } } }