并查集

并查集

  • 摘要
  • 什么是并查集
  • 并查集的实现

超级详细的基础算法和数据结构合集:
https://blog.csdn.net/GD_ONE/article/details/104061907

摘要

本文主要介绍并查集和其效率最高并且最简单的实现方式。

什么是并查集

并查集顾名思义,是一种用于处理集合与集合之间查询和合并等操作的数据结构。比如询问两点是否在同一集合,将两个不同集合合并等

并查集的实现

给出n个点,将其划分为两个集合,查询其中某两个点是否在同一集合内,你会怎么做?

简单的方法就是,将同一个集合内的所有点设置一个标记,然后查询两个点的标记是否一样。其实这就是并查集了:

  1. 首先开一个数组, 存n个点

    int p[N];	
    
  2. 刚开始每个点都在不同的集合,所以初始化让每个点都指向自己

    for(int i = 1; i <= n; i++) p[i] = i; //并查集初始化
    
  3. 那么让两个不用的集合合并呢?很简单,让其中一个点指向另一个点

    p[a] = b;  // 将a连接到b所在的集合内
    或者
    //p[b] = a;  //将b连接到a所在的集合内
    
  4. 那么问题来了,直接让p[a] = b, 那查询的时候肯定会出错的,因为每个点所指向的点都不一样,前面说了,要将同一个集合内的点指向同一个标记,所以p[a] 指向的点应该是b的标记,也就是p[b]的父节点
    也就是p[a] = p[b];但是如果b指向不是那个标记,也就是最终的父节点,这时就又出错了。所以我们要让每个点都指向最终的父结点,也就是那个标记。所以我们要先找到父节点。某一个点指向自己,那么它就是父节点,其他点均指向它。
    此find函数是并查集的精髓所在

 public static int find(int x){
    if(p[x] != x) p[x] = find(p[x]);// p[x] != x 说明p[x]指向的不是父节点
    return p[x];                   // 在搜索父节点的同时更新p[x]让其指向父节点
 }

图示:

并查集_第1张图片
并查集_第2张图片
并查集_第3张图片
这时应该让4指向3 而不是否则查询2,4是否在同一个集合肯定会出错的

所以,find很重要,不能写错了。
并查集有很多种用途,还有很多扩展。这里只介绍并查集是什么,以及最简单的实现方式。

你可能感兴趣的:(基础数据结构,蓝桥杯,并查集,java,数据结构)