数据结构与算法之并查集-1

75 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情

✨欢迎关注🖱点赞🎀收藏⭐留言✒

🔮本文由京与旧铺原创,csdn首发!

😘系列专栏:java学习

💻首发时间:🎞2022年12月10日🎠

🀄如果觉得博主的文章还不错的话,请三连支持一下博主哦

🎧作者是一个新人,在很多方面还做的不好,欢迎大佬指正,一起学习哦,冲冲冲

🎀🎀🎀今日分享:这一年大概是我长这么大,最难熬的一年,也是让我成长最多的一年,感谢生活赐予我一场惊慌失措,但愿以后抬头由阳光

🐱‍💻导航小助手

1.并查集介绍

并查集是一种能够进行分组管理的数据结构,该数据结构可以实现以下几种功能:

  • 能够管理多个小的集合。
  • 能够将两个不相交的集合合并到一个集合当中(union)。
  • 能够查找某个元素在哪一个小集合当中(find)。

0-1

在生活当中,分组是非常常见的,最典型的栗子就是在一个班中,老师常常会将班级里面的同学分为很多组,假设我们使用数字来表示组员,假设一个班中有4组,每一组6个人,一共24个人,每一个组都会有一个小组长,老师任命1号位第一小组组长,8号位第二小组组长,15号为第三小组组长,22号为第四小组组长,1-6号组成第一小组,7-12号为组成二小组,13-18号组成第三小组,剩下的19-24号为第四小组成员,老师特别强调每个小组成员都要知道自己的小组长是谁,于是我们可以使用下面这一张图来描述这一个场景。

1 并查集这个数据结构可以进行分组管理,它可以查询组员是哪一组的,还可以将两个小组合并到一起。

2.并查集的简单实现

2.1并查集结构

并查集的实现可以使用数组,接下来还是依照上面的例子来说,一共有24个同学,我们就可以申请24个空间(为了下标能够与上面举例子同学编号对应我们多申请一个空间)来存放元素,不妨使用数组p来表示并查集中的数组,需要实现查找某个同学的班长是谁(查找某元素的根结点)和实现合并两小组(即合并两个不相交的集合)。

其中数组下标表示某个组员的编号,数组中存储的元素就是组长的编号。

我们采用UnionFindSet来表示并查集的类,类结构如下:

java代码

import java.util.*;
​
class UnionFindSet {
    private int[] p;
    
    public UnionFindSet(int cap) {
        p = new int[cap + 1];
        //将所有的元素都指向自己
        for (int i = 1; i <= cap; i++) {
            p[i] = i;
        }
    }
    
    //重置数组
    public void init() {
        for (int i = 1; i < p.length; i++) {
            p[i] = i;
        }
    }
    
    //查找某个元素的根结点
    public int find(int x) {
        //...
    }
    //合并两个集合
    public void union(int a, int b) {
        //...
    }
}

c++代码:

#include <iostream>
#include <algorithm>
#include <string>using namespace std;
​
class UnionFindSet 
{
private:
    int* p;
    int _cap;
​
public:
    //构造函数
    UnionFindSet(int cap) 
    {
        p = (int*) malloc(sizeof(int) * (cap + 1));
        _cap = cap;
        //将所有元素初始化
        for (int i = 1; i <= cap; i++)
        {
            p[i] = i;
        }
    }
    
    //将元素重置
    void clear() 
    {
        for (int i = 1; i < _cap; i++) 
        {
            p[i] = i;
        }
    }
​
    //查找某元素的根
    int find(int x) 
    {
        //...
    }
​
    //union合并两个集合
    void _union(int a, int b)
    {
        //...
    }
};