并查集-理论知识

248 阅读1分钟

概念

并查集(union & find)是一种树形数据结构,用于处理不交集的查找和合并。

find:确定元素属于哪个子集;判断两个元素是否属于同一个子集。

union:合并两个子集。

拆分复杂,通常不支持也不常用拆分。

作用

帮派识别

数据结构实现和代码

数组

public class QuickUnionUF {

    private int[] roots;

    public QuickUnionUF(int N) {
        roots = new int[N];
        for (int i = 0; i < N; i++) {
            roots[i] = i;
        }
    }
}

roots[i] = i 表示节点上级为自己

伪代码如下

    function MakeSet(x)
        x.root := x
        
    function Find(x)
        if x.root := x
            return x
        else
            return Find(x.root)
            
    function Union(x, y)
        xRoot := Find(x)
        yRoot := Find(y)
        xRoot.root = yRoot

两种优化方式

  1. 合并的时候减少树的深度(rank),把深度低的子集merge到深度高的子集上
    function MakeSet(x)
        x.root := x
        x.rank := 0
        
    function Union(x, y)
        xRoot := Find(x)
        yRoot := Find(y)
        if yRoot.rank > xRoot.rank
            xRoot.root := yRoot
        else if yRoot.rank < xRoot.rank
            yRoot.root := xRoot
        else
            xRoot.root := yRoot
            yRoot.rank := yRoot.rank + 1
  1. 路径压缩,直接找到最大的老大赋值为直接上级
    public int Find(int x) {
        int root = x;
        while (root != roots[root]) root = roots[root];
        
        while (x != roots[x]) {
            int tmp = roots[x];roots[x] = root;x = tmp;
        }
        return root;
    }