并查集

一共两个函数

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.")
        }
    }


}
原文地址:https://www.cnblogs.com/da-peng/p/11581278.html