算法篇 : 并查集

介绍

英文名:union find set

作用:合并集合,查询集合

合并:将有直接关系的顶点放在一个集合里面

查找:查询某个顶点所属的集合

集合的标志:用祖先点的标号作为每个集合的标识

案例

如果说将下图的集合2合并至集合1

那么应该让3的祖先为1,即:

实现流程

1)对所有顶点标号,其祖先节点默认为自己

2)合并:以两个点中祖先标号小的作为新祖先进行合并

3)查找:查找点的祖先,并更新查找路径点的祖先

Java代码实现
java 复制代码
//顶点类
public class Vertex {
    public Integer id;
    public Vertex(Integer id){
        this.id=id;
    }
}

//并查集的操作类
public class UnionFindSetOperator {
    private List<Vertex>vertexs;    //所有顶点
    private List<List<Vertex>>connectVertexs;    //所有有直接关系的顶点
    private Map<Vertex,Vertex>ancestor;
    public UnionFindSetOperator(List<Vertex> vertexs, List<List<Vertex>> connectVertexs) {
        this.vertexs = vertexs;
        this.connectVertexs = connectVertexs;
        this.ancestor=new HashMap<>();
        //将所有顶点的祖先初始化默认设置为自己
        for(int i=0;i< vertexs.size();i++)
        {
            ancestor.put(vertexs.get(i),vertexs.get(i));
        }
        //合并所有直接相连的顶点
        for(int i=0;i< connectVertexs.size();i++)
        {
            Union(connectVertexs.get(i).get(0),connectVertexs.get(i).get(1));
        }
    }
    public void Union(Vertex vertex1,Vertex vertex2){
        Vertex ancestor1=Find(vertex1);
        Vertex ancestor2=Find(vertex2);
        //选取两个祖先id小的作为新祖先
        if(ancestor1.id<ancestor2.id)
            ancestor.put(vertex2,ancestor1);
        else
            ancestor.put(vertex1,ancestor2);
    }

    public Vertex Find(Vertex vertex){
        if(ancestor.get(vertex)!=vertex)
        {
            //寻找该节点的祖先
            Vertex ancestorVertex=Find(ancestor.get(vertex));
            //如果祖先发生了变化,则更新记录新的祖先
            if(ancestorVertex!=ancestor.get(vertex))
                ancestor.put(vertex,ancestorVertex);
        }
        //返回其祖先
        return ancestor.get(vertex);
    }
}
测试函数
java 复制代码
//测试函数
public class Main {
    /*
        并查集:
            简述:对集合进行分类合并,方便后续查找
            实现步骤:
                1)对所有顶点标号,其祖先节点默认为自己

                2)合并:以两个点中祖先标号小的作为新祖先进行合并

                3)查找:查找点的祖先,并更新查找路径点的祖先

     */
    public static void main(String[] args) {
        //扫描器
        Scanner scanner=new Scanner(System.in);

        //存放顶点
        List<Vertex>vertexs=new LinkedList<>();

        //有直接关联的顶点
        List<List<Vertex>>connectVertexs=new LinkedList<>();

        System.out.println("请输入顶点的数量:");
        Integer vexcnt= scanner.nextInt();

        System.out.println("请输入这些顶点的编号");
        for(int i=0;i<vexcnt;i++)
        {
            vertexs.add(new Vertex(scanner.nextInt()));
        }

        System.out.println("请输入有关系顶点的对数:");
        Integer connectVertexCnt= scanner.nextInt();

        System.out.println("请输入有关系顶点的编号:");
        for(int i=0;i<connectVertexCnt;i++)
        {
            Integer id1= scanner.nextInt();
            Integer id2= scanner.nextInt();

            //获取这两个顶点
            Vertex v1=null;
            Vertex v2=null;

            for(int j=0;j<vertexs.size();j++)
            {
                if(vertexs.get(j).id==id1)
                    v1=vertexs.get(j);
                if(vertexs.get(j).id==id2)
                    v2=vertexs.get(j);
            }
            LinkedList<Vertex>conVertexs=new LinkedList<>();
            conVertexs.add(v1);
            conVertexs.add(v2);
            connectVertexs.add(conVertexs);
        }

        //用并查集的操作类实现这些点的分类和查找
        UnionFindSetOperator ufs=new UnionFindSetOperator(vertexs,connectVertexs);

        //查找每一个点的祖先
        for(int i=0;i<vertexs.size();i++)
        {
            Vertex ancestor=ufs.Find(vertexs.get(i));
            System.out.println("顶点:"+vertexs.get(i).id+"的祖先id为:"+ancestor.id);
        }

    }
}
自测

测试模型:

测试结果:

相关推荐
夏末秋也凉1 小时前
力扣-回溯-491 非递减子序列
数据结构·算法·leetcode
老菜鸡mou2 小时前
[OD E 100] 生成哈夫曼树
数据结构·c++
和光同尘@3 小时前
56. 合并区间 (LeetCode 热题 100)
c语言·开发语言·数据结构·c++·算法·leetcode·职场和发展
CS创新实验室4 小时前
计算机考研之数据结构:大 O 记号
数据结构·考研
wen__xvn5 小时前
每日一题洛谷P1914 小书童——凯撒密码c++
数据结构·c++·算法
BUG 劝退师6 小时前
八大经典排序算法
数据结构·算法·排序算法
小小小白的编程日记6 小时前
List的基本功能(1)
数据结构·c++·算法·stl·list
_Itachi__6 小时前
LeetCode 热题 100 283. 移动零
数据结构·算法·leetcode
柃歌6 小时前
【UCB CS 61B SP24】Lecture 5 - Lists 3: DLLists and Arrays学习笔记
java·数据结构·笔记·学习·算法
商bol457 小时前
复习dddddddd
数据结构·c++·算法