并查集:

并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中,其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1~3秒)内计算出试题需要的结果,只能用并查集来描述。(来自百度百科)

关于并查集的实现,有两种思路.
一种是基于数组 ,这种思路是将每个元素所属的集合编号存在数组中,然后随着集合编号的合并和,修改数组的编号即可,代码实现如下

首先定义一个并查集的接口:

/*** @author BestQiang*/
public interface UF {int getSize();boolean isConnected(int p, int q);void unionELements(int p, int q);
}

接下来实现并查集接口:

/*** @author BestQiang*/
public class UnionFind1 implements UF {private int[] id;public UnionFind1(int size) {// 初始化并查集,此时所有元素属于不同的集合this.id = new int[size];for (int i = 0; i < id.length; i++) {id[i] = i;}}@Overridepublic int getSize() {return 0;}/*** 查找元素p所对应的的集合编号* @param p* @return*/private int find(int p) {if(p < 0 && p >= id.length) {throw new IllegalArgumentException("p is out of bound.");}// 直接返回对应的集合编号即可return id[p];}/*** 查看元素p和元素q是否所属一个集合* @param p* @param q* @return*/@Overridepublic boolean isConnected(int p, int q) {return find(p) == find(q);}/*** 合并元素p和元素q所属的集合* @param p* @param q*/@Overridepublic void unionELements(int p, int q) {// 首先判断是否同属一个集合,如果属于一个集合,直接结束即可,因为不需要合并int pID = find(p);int qID = find(q);if(pID == qID) {return;}// 循环宾利数组,将原来属于一个集合的元素的所属集合修改为新的集合for (int i = 0; i < id.length; i++) {if(id[i] == pID) {id[i] = qID;}}}}

另一种是基于树 ,这种树不是一般的树,这种树是由下层节点指向上层节点的树,基于数组实现,如图所示:

将数组的值储存为父节点的id即可,代码实现如下:

/*** @author BestQiang*/
public class UnionFind2 implements UF{private int[] parent;public UnionFind2(int size) {parent = new int[size];for(int i = 0; i < size; i++) {parent[i] = i;}}@Overridepublic int getSize() {return parent.length;}/***  查找过程,查找元素p所对应的集合编号*  O(h)复杂度,h为树的高度* @param p* @return*/private int find(int p) {if(p < 0 && p >= parent.length) {throw new IllegalArgumentException("p is out of bound");}// 循环查找p的根节点(原理是查找p的上层节点,找到后将上层节点赋值给p,继续找上层节点,相同才截止)while (p != parent[p]) {p = parent[p];}return p;}/*** 查看元素p和元素q是否所属一个集合* O(h)复杂度, h为树的高度* @param p* @param q* @return*/@Overridepublic boolean isConnected(int p, int q) {// 如果根节点相同,直接判定为所属一个集合return find(p) == find(q);}/*** 合并两个节点* @param p* @param q*/@Overridepublic void unionELements(int p, int q) {int pRoot = find(p);int qRoot = find(q);// 根节点相同,代表已经所属同组,直接结束即可if(pRoot == qRoot) {return;}// 根节点不同,就将pRoot的上层设置到q的根节点即可// 为什么要直接连接到qRoot的根节点,不直接连接到qRoot的上层节点?目的是发挥树的特性,便于查询parent[pRoot] = qRoot;}
}

简单实现并查集(基于数组和基于树)相关推荐

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

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

  2. P2178 [NOI2015] 品酒大会(并查集+后缀数组)

    LINK T1\color{Red}{T1}T1 第ppp杯酒和第qqq杯酒的最大相似度就是LCP(suffix(p),suffix(q))LCP(suffix(p),suffix(q))LCP(su ...

  3. [学习笔记]可持久化数据结构——数组、并查集、平衡树、Trie树

    可持久化:支持查询历史版本和在历史版本上修改 可持久化数组 主席树做即可. [模板]可持久化数组(可持久化线段树/平衡树) 可持久化并查集 可持久化并查集 主席树做即可. 要按秩合并.(路径压缩每次建 ...

  4. codeforces 884E Binary Matrix 并查集,滚动数组

    E. Binary Matrix time limit per test 3 seconds memory limit per test 16 megabytes input standard inp ...

  5. 基于C语言,详解Kruskal算法(利用并查集)实现构建最小生成树

    目录 一.Kruskal算法的基本介绍 具体做法:找出森林中连接任意两棵树的所有边中,具有最小权值的边,如果将它加入生成树中不产生回路,则它就是生成树中的一条边.这里的关键就是如何判断"将它 ...

  6. hdu1232(简单并查集)

    畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

  7. 并查集(边带权,拓展域)

    整理的算法模板合集: ACM模板 目录 朴素并查集 维护size的并查集 维护到祖宗节点距离的并查集 路径压缩和按秩合并 2.5 边带权 带权并查集求二分图最小环 2.6 扩展域 2.7 集合中单个元 ...

  8. 谈一谈并查集QAQ(上)

    最近几日理了理学过的很多oi知识...发现不知不觉就有很多的知识忘记了... 在聊聊并查集的时候顺便当作巩固吧.... 什么是并查集呢? ( Union Find Set ) 是一种用于处理分离集合的 ...

  9. 数据结构 5-4-1 并查集

    一.概念 并查集本质上是对树的知识的利用,常用于集合的相关表示,不同于一般的二叉树,并查集用的是指向双亲节点的指针,便于分类而不便于找子节点, 二.代码实现 简单的并查集主要有三个函数,初始化.合并. ...

最新文章

  1. Ansible批量添加远程登录用户
  2. Nginx的File not found 错误解决
  3. 火了!16岁高中生做的 Python 3.9 八大新特性图
  4. 从C++20 shared_ptr移除unique()方法浅析多线程同步
  5. 点击率预测算法:FTRL
  6. it精英挑战赛的规则 校区内部评选 2020
  7. matlab设置背景颜色
  8. MCSE第六课-DHCP
  9. 01-路由跳转 安装less this.$router.replace(path) 解决vue/cli3.0语法报错问题
  10. 通过dSYM文件分析crash日志
  11. 九九乘法表打印Python
  12. 国内十大白银期货APP最新排名
  13. Eclipse TPTP 分析程序性能
  14. Kali Linux渗透测试 128 拒绝服务--TearDrop 攻击
  15. 前端开发中的脚手架是什么意思
  16. 未明学院:Tableau安装详细教程,带你攻克第一个学习难关!
  17. 解决ROS中运行launch文件报错ERROR: cannot launch node of type[xxx/xxx]:xxx的问题办法最全汇总
  18. 100教程-100jc.cn
  19. mac安装win10_AMD黑苹果+win10双系统安装
  20. 纽约研究人员称人工智能才是理解量子系统的关键所在

热门文章

  1. H.264编码基础知识详解
  2. python离线下载第三方库
  3. Arcmap转nc文件为TIFF格式(以逐月降水量数据集转年均数据为例)
  4. 浙江中级聘用计算机还需要吗,浙江省中级高级职称计算机考试要考几个模块?...
  5. Linux Shell 通配符、元字符、转义符使用实例介绍--Learning the korn shell
  6. 微信公众号最佳实践 ( 4.4)客服接口
  7. http://www.jianshu.com/p/55458caf0814
  8. 用ch340烧录stm32
  9. 潮州赤凤田湖溯溪历险记
  10. 网易服务器维护,网易15日未停服维护,所有服务器正常运行中