算法篇 : 并查集

介绍

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

    }
}
自测

测试模型:

测试结果:

相关推荐
半盏茶香8 分钟前
启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——堆的应用之堆排、Top-K问题
java·开发语言·数据结构·c++·python·算法·链表
小竹子1431 分钟前
L1-1 天梯赛座位分配
数据结构·c++·算法
Phoebe鑫2 小时前
数据结构每日一题day9(顺序表)★★★★★
数据结构·算法
南玖yy3 小时前
数据结构C语言练习(栈)
c语言·数据结构·算法
MPCTHU4 小时前
二叉树、排序算法与结构图
数据结构·算法·排序算法
wuqingshun3141594 小时前
蓝桥杯 XYZ
数据结构·c++·算法·职场和发展·蓝桥杯
南玖yy4 小时前
数据结构C语言练习(两个队列实现栈)
c语言·数据结构·算法
loser~曹5 小时前
基于快速排序解决 leetcode hot215 查找数组中第k大的数字
数据结构·算法·leetcode
SylviaW085 小时前
python-leetcode 62.搜索插入位置
数据结构·算法·leetcode
丶Darling.5 小时前
26考研 | 王道 | 数据结构 | 第四章 串
数据结构·考研·kmp