孙汉清吧 关注:17贴子:232
  • 3回复贴,共1

【算法分享】数据结构-并查集

取消只看楼主收藏回复

并查集是一种数据结构,用于处理一些不交集(Disjoint Sets)的合并及查询问题。它支持两种操作:
查找(Find):确定某个元素属于哪个子集。这通常通过查找该元素的“根元素”来实现,根元素是指某个集合中最顶层的代表元素。
合并(Union):将两个子集合并为一个集合。这通常通过将一个集合的根元素连接到另一个集合的根元素上来实现。
并查集的一个关键特性是能够非常快速地执行这两种操作,尤其是当并查集通过一些优化措施(如路径压缩和按秩合并)实现时,其时间复杂度几乎可以认为是常数时间。
并查集被广泛应用于各类算法中,尤其是那些涉及到元素分组、网络连接性判断、最小生成树、图的连通分量分析等场景。


IP属地:河南1楼2024-03-15 22:20回复
    示例应用场景
    假设我们有一些元素,需要经常查询它们是否在同一个组内或者需要将两个组合并。这种场景在很多问题中都会出现,例如:
    社交网络中的好友关系分析。
    图中的连通分量(Connected Components)判断。
    最小生成树算法,如Kruskal算法。


    IP属地:河南2楼2024-03-15 22:20
    回复
      核心操作
      初始化(MakeSet):开始时,每个元素自成一组,即每个元素都是自己集合的代表。
      查找(Find):找到元素所在集合的代表元素,这可以通过递归查找父节点直到找到根节点实现。
      合并(Union):将两个元素所在的集合合并为一个集合,通常是将一个集合的根节点指向另一个集合的根节点。
      通过这些操作,我们可以有效地解决很多与集合、分组和连通性相关的问题。


      IP属地:河南3楼2024-03-15 22:21
      回复
        (1)朴素并查集:
        int p[N]; //存储每个点的祖宗节点
        // 返回x的祖宗节点
        int find(int x)
        {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
        }
        // 初始化,假定节点编号是1~n
        for (int i = 1; i <= n; i ++ ) p[i] = i;
        // 合并a和b所在的两个集合:
        p[find(a)] = find(b);
        (2)维护size的并查集:
        int p[N], size[N];
        //p[]存储每个点的祖宗节点, size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量
        // 返回x的祖宗节点
        int find(int x)
        {
        if (p[x] != x) p[x] = find(p[x]);
        return p[x];
        }
        // 初始化,假定节点编号是1~n
        for (int i = 1; i <= n; i ++ )
        {
        p[i] = i;
        size[i] = 1;
        }
        // 合并a和b所在的两个集合:
        size[find(b)] += size[find(a)];
        p[find(a)] = find(b);
        (3)维护到祖宗节点距离的并查集:
        int p[N], d[N];
        //p[]存储每个点的祖宗节点, d[x]存储x到p[x]的距离
        // 返回x的祖宗节点
        int find(int x)
        {
        if (p[x] != x)
        {
        int u = find(p[x]);
        d[x] += d[p[x]];
        p[x] = u;
        }
        return p[x];
        }
        // 初始化,假定节点编号是1~n
        for (int i = 1; i <= n; i ++ )
        {
        p[i] = i;
        d[i] = 0;
        }
        // 合并a和b所在的两个集合:
        p[find(a)] = find(b);
        d[find(a)] = distance; // 根据具体问题,初始化find(a)的偏移量


        IP属地:河南5楼2024-03-15 22:21
        回复