算法篇 : 并查集

介绍

英文名: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);
        }

    }
}
自测

测试模型:

测试结果:

相关推荐
学嵌入式的小杨同学3 小时前
【嵌入式 C 语言实战】交互式栈管理系统:从功能实现到用户交互全解析
c语言·开发语言·arm开发·数据结构·c++·算法·链表
多米Domi0113 小时前
0x3f 第40天 setnx的分布式锁和redission,写了一天项目书,光背了会儿八股,回溯(单词搜索)
数据结构·算法·leetcode
历程里程碑4 小时前
Linux 3 指令(3):进阶指令:文件查看、资源管理、搜索打包压缩详解
linux·运维·服务器·c语言·数据结构·笔记·算法
一分之二~4 小时前
二叉树--求最小深度(迭代和递归)
数据结构·c++·算法·leetcode·深度优先
wWYy.5 小时前
详解redis(8):数据结构Hash
数据结构·redis·哈希算法
智者知已应修善业5 小时前
【输出一个N*N的01矩阵,表示最后的汉字点阵图】2024-10-22
c语言·数据结构·c++·经验分享·笔记·算法·矩阵
uesowys5 小时前
华为OD算法开发指导-二级索引
数据结构·算法·华为od
Sheep Shaun6 小时前
C++11核心特性详解:从右值引用到现代C++编程
开发语言·数据结构·c++·算法
云深麋鹿6 小时前
三.栈和队列
开发语言·数据结构·c++·算法
Python_Study20257 小时前
工程材料企业如何通过智慧获客软件破解市场困局:方法论、架构与实践
大数据·网络·数据结构·人工智能·架构