并查集就是将原本不在一个集合里面的内容合并到一个集合中。
在实际的场景中用处不多。

除了出现在你需要同时去几个集合里面查询,避免出现查询很多次,从而放在一起查询的情况。

下面简单实现一个例子,我们来举例说明一下什么是并查集,以及究竟并查集解决了什么问题。

代码解析

package com.chaojilaji.book.andcheck;public class AndCheckSet {public static Integer getFather(int[] father, int u) {if (father[u] != u) {father[u] = getFather(father, father[u]);}return father[u];}public static void join(int[] father,int x, int y) {int fx = getFather(father,x);int fy = getFather(father,y);if (fx != fy){father[fx] = fy;}}public static void main(String[] args) {int n = 10;int[] a = new int[n];for (int i = 0;i<n;i++){a[i] = i; // 初始化定义一百个集合}for (int i=0;i<n;i++){System.out.println(i+" "+getFather(a, i)); // 对于每个集合,父节点都是自己}}
}
复制代码

首先,我们定义了两个函数,分别为getFather和join,分别表示获取u所在集合的根以及合并两个集合。

先来看看getFather方法

public static Integer getFather(int[] father, int u) {if (father[u] != u) {father[u] = getFather(father, father[u]);}return father[u];
}
复制代码

是找出值u所在集合的根节点是多少。一般来说,father[u]如果等于u本身,那么说明u所在节点就是根节点,而这个算法是直到相等才退出,也就是说,对于从u到根节点的每个节点的father都被直接置为根节点,同时返回了当前节点的根节点。

然后来看看join方法

public static void join(int[] father,int x, int y) {int fx = getFather(father,x);int fy = getFather(father,y);if (fx != fy){father[fx] = fy;}
}
复制代码

分别找出x和y两个节点所在集合的根节点,如果根节点不一样,则将其中一个节点的father节点置为另一个节点即可,这样就合并成了一个集合。

代码应用

public static void main(String[] args) {int n = 10;int[] a = new int[n];for (int i = 0;i<n;i++){a[i] = i; // 初始化定义n个集合}for (int i=0;i<n;i++){System.out.println(i+" "+getFather(a, i)); // 对于每个集合,父节点都是自己}System.out.println("-------------------------");join(a,0,1); // 合并 0 和 1for (int i=0;i<n;i++){System.out.println(i+" "+getFather(a, i));}// 由于合并了0和1,所以集合变成了9个,节点0和节点1的根都是节点1System.out.println("-------------------------");join(a,2,3); // 合并 2 和 3for (int i=0;i<n;i++){System.out.println(i+" "+getFather(a, i));}// 由于合并了2和3,所以集合变成8个,节点2和节点3的根都是节点3System.out.println("-------------------------");join(a,1,3); // 合并 1 和 3for (int i=0;i<n;i++){System.out.println(i+" "+getFather(a, i));}// 由于合并了1和3,所以集合变成7个,节点0,1,2,3的根都是节点3
}
复制代码

首先,我们定义了n个集合,这n个集合的值是0~n-1,然后此时他们的父节点均等于他们本身,所以这就是n个独立的集合,结果如下

0的父节点为 0 1的父节点为 1 2的父节点为 2 3的父节点为 3 4的父节点为 4 5的父节点为 5 6的父节点为 6 7的父节点为 7 8的父节点为 8 9的父节点为 9

然后调用 join(a,0,1)合并0集合和1集合,再输出节点父集合情况为

0的父节点为 1 1的父节点为 1 2的父节点为 2 3的父节点为 3 4的父节点为 4 5的父节点为 5 6的父节点为 6 7的父节点为 7 8的父节点为 8 9的父节点为 9

可以看见,由于合并了0和1,所以集合变成了9个,节点0和节点1的根都是节点1。
然后调用 join(a,2,3) 合并2集合和3集合,输出节点父集合情况为

0的父节点为 1 1的父节点为 1 2的父节点为 3 3的父节点为 3 4的父节点为 4 5的父节点为 5 6的父节点为 6 7的父节点为 7 8的父节点为 8 9的父节点为 9

可以看见,由于合并了2和3,所以集合变成8个,节点2和节点3的根都是节点3。
最后,我们再调用join(a,1,3) 合并1集合和3集合,输出节点父集合情况为

0的父节点为 3 1的父节点为 3 2的父节点为 3 3的父节点为 3 4的父节点为 4 5的父节点为 5 6的父节点为 6 7的父节点为 7 8的父节点为 8 9的父节点为 9

可以看出来,由于合并了1和3,所以集合变成7个,节点0,1,2,3的根都是节点3。

实际应用

代码的层面来讲,并查集很好实现。但是我们却也可以发现,其应用场景似乎非常局限。
首先,我们需要定义出一个father[x] = x的数组,然后我们再去合并。似乎很难想到应用场景。

那么我们可以想象一个场景,现在有个网络拓扑图,里面有n和网络设施设备,然后又给了你这n个设施设备之间的连接关系,问你一共有多少个局部联通网。
对于这个问题,我们就可以首先定义每个设备自己跟自己相连,然后每出现一条边,就对这两个设备采取join操作。最终我们在遍历完所有的节点,得到多少个不同的father,即表示有多少个不同的局部联通网。

这样的问题还可以延伸到我们的人际交友圈,首先每个人都是单独的集合,在不断认识人的过程中,产生连通性。最终让你确认一共有多少个不互通的人际圈。

所以你会发现,这本质上就是求图论中连通块的个数。

用Java实现并查集相关推荐

  1. hdu1181变形课dfs/bfs/并查集三种解法(java)

    题目链接 Problem Description 呃-变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个 ...

  2. java最简单的并查集(不想交集合)以及杭电1272

    并查集要有的一些属性:value:表示当前值,指针:(不一定是指针)指向父节点. 还有一个属性number:表示该树存在的总个数.(也可以用深度表示).我用小树插在大树上. 如果是普通数字表示的树,可 ...

  3. HYSBZ - 1050(旅行comf 并查集Java实现)

    HYSBZ - 1050(旅行comf Java实现) 原题地址 解法:枚举每一条边,对于这条边,我们需要找到集合中和其值相差最小的最大边,这个集合是指与包括i边在内的ST联通集.对于这一要求,我们只 ...

  4. [Leedcode][JAVA][第200题][岛屿数量][DFS][BFS][并查集]

    [问题描述] 第200题 岛屿数量 给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量.岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成 ...

  5. 堆的应用--并查集解决“擒贼先擒王”问题(JAVA)

    现在有10个强盗. 1号强盗与2号强盗是同伙. 3号强盗与4号强盗是同伙. 5号强盗与2号强盗是同伙. 4号强盗与6号强盗是同伙. 2号强盗与6号强盗是同伙. 8号强盗与7号强盗是同伙. 9号强盗与7 ...

  6. 挑战程序设计竞赛(算法和数据结构)——14.1互质的集合(并查集)的JAVA实现

    题目与思路: 代码: import java.util.Scanner; import java.util.Vector;public class DisjointSet {public static ...

  7. java并查集_一个非常实用而且精妙的算法-并查集(java语言实现)

    在学习数据结构的时候,老师多少会提到并查集,他的应用也是超级广泛.本文首先会通过案例来对并查集有一个介绍.然后给出并查集的java实现. 一.并查集原理 话说在江湖上有很多门派,这些门派相互争夺武林霸 ...

  8. hdu dfs入门java_hdu1181变形课dfs/bfs/并查集三种解法(java)

    题目链接 Problem Description 呃-变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个 ...

  9. 【数据结构与算法基础】并查集原理、封装实现及例题解析(C和java)

    前言 数据结构,一门数据处理的艺术,精巧的结构在一个又一个算法下发挥着他们无与伦比的高效和精密之美,在为信息技术打下坚实地基的同时,也令无数开发者和探索者为之着迷. 也因如此,它作为博主大二上学期最重 ...

  10. java并查集计算机网络连通,poj2236 Wireless Network(并查集)

    题意:有n台损坏的电脑,现要将其逐台修复,且使其相互恢复通信功能.若两台电脑能相互通信,则有两种情况,一是他们之间的距离小于d,二是他们可以借助都可到达的第三台已修复的电脑.给出所有电脑的坐标位置,对 ...

最新文章

  1. IJCAI 2021 医药AI必读论文推荐
  2. java新建常量_【Java】常量 - 每日坚果的个人空间 - OSCHINA - 中文开源技术交流社区...
  3. JAVA线程本地变量ThreadLocal和私有变量的区别
  4. why is pricing callback CRM_PRIDOC_UPDATE_EC called
  5. 洛谷 P1736 创意吃鱼法
  6. 基于java TCP实现网络通信聊天室《建议收藏附完整源码》
  7. 关于Python的一切:2018年,你读这8本书就够了
  8. 机器学习之网格搜索(GridSearch)及参数说明,实例演示
  9. 火狐浏览器插件汇总(VIP典藏版)
  10. sap成本流怎么看_SAP标准成本核算体系
  11. linux安装命令自动运行y,在Linux上安装Gnome Tweak以在Gnome Shell上自动启动程序
  12. 838计算机考研用书,河海计算机838考研大纲(5页)-原创力文档
  13. 危机管理应遵循哪些原则?
  14. matlab应用测试,moocMATLAB程序与应用单元测试答案
  15. 最好用的矢量绘图软件Sketch mac中文72.3
  16. 无人驾驶汽车系统入门(二十三)——迁移学习和端到端无人驾驶
  17. MATLAB笔记1:sub2ind;ind2sub;删除矩阵某行或者某列元素;改变矩阵的形状reshape函数
  18. 2019年,中国即将发生的45个重大变化!
  19. 物联网毕设 单片机 嵌入式 题目选题推荐
  20. VAN:Visual Attention Network

热门文章

  1. 微信商城的这六大优势,以及这些丰富的功能,你知道吗?
  2. jmp怎么做合并的箱线图_基于JMP 15的箱线图(Box Plot)的着色
  3. 微信公众号模板消息推送
  4. WinMTR-路由追踪软件
  5. 网络调试助手(模拟下位机收发数据)快速指南
  6. UV的入门使用方法,简单,快捷,包教包会
  7. ECshop新手入门模板制作教程[转载]
  8. 小程序场景二维码扫码
  9. 我的大学四年到毕业工作5年的学习路线资源汇总
  10. 计算机二级题库病毒,计算机二级MS Office题库