首发公众号:bigsai

认识并查集

对于并查集(不相交集合),很多人会感到很陌生没听过或者不是特别了解。实际上并查集是一种挺高效的数据结构。实现简单,只是所有元素统一遵从一个规律所以让办事情的效率高效起来。

对于定意义,百科上这么定义的:

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

并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。

并查集解析

基本思想

  • 初始化,一个森林每个都为独立。通常用数组表示,每个值初始为-1。各自为根
  • join(a,b) 操作。a,b两个集合合并。注意这里的a,并不是a,b合并,而是a,b的集合合并。这就派生了一些情况:
  • a,b如果是独立的(没有和其他合并),那么直接a指向b(或者b指向a),即data[a]=b;同时为了表示这个集合有多少个,原本-1的b再次-1.即data[b]=-2.表示以b为父亲的节点有|-2|个。
  • a,b如果有集合(可能有父亲,可能自己是根),那么我们当然不能直接操作a,b(因为a,b可能已经指向别人了.)那么我们只能操作a,b的祖先。因为a,b的祖先是没有指向的(即数据为负值表示大小)。那么他们首先一个负值要加到另外一个上面去。另外这个数值要变成指向的那个表示联系。

对于上述你可能会有疑问:

如何查看a,b是否在一个集合?

  • 查看是否在一个集合,只需要查看节点根祖先的结果是否相同即可。因为只有根的数值是负的,而其他都是正数表示指向的元素。所以只需要一直寻找直到不为正数进行比较即可

a,b合并,究竟是a的祖先合并在b的祖先上,还是b的祖先合并在a上?

  • 这里会遇到两种情况,这个选择也是非常重要的。你要弄明白一点:树的高度+1的化那么整个元素查询的效率都会降低!

所以我们通常是:小数指向大树(或者低树指向高树),这个使得查询效率能够增加!

当然,在高度和数量的选择上,还需要你自己选择和考虑。

其他路径压缩?

每次查询,自下向上。当我们调用递归的时候,可以顺便压缩路径,因为我们查找一个元素其实只需要直到它的祖先,所以当他距离祖先近那么下次查询就很快。并且压缩路径的代价并不大!

代码实现

并查集实现起来较为简单,直接贴代码!

package 并查集不想交集合;import java.util.Scanner;
public class DisjointSet {static int tree[]=new int[100000];//假设有500个值public DisjointSet()    {set(this.tree);}public DisjointSet(int tree[]) {this.tree=tree;set(this.tree);}public void set(int a[])//初始化所有都是-1 有两个好处,这样他们指向-1说明是自己,第二,-1代表当前森林有-(-1)个{int l=a.length;for(int i=0;i<l;i++){a[i]=-1;}}public int search(int a)//返回头节点的数值{if(tree[a]>0)//说明是子节点{return tree[a]=search(tree[a]);//路径压缩}elsereturn a;}public int value(int a)//返回a所在树的大小(个数){if(tree[a]>0){return value(tree[a]);}elsereturn -tree[a];}public void union(int a,int b)//表示 a,b所在的树合并{int a1=search(a);//a根int b1=search(b);//b根if(a1==b1) {System.out.println(a+"和"+b+"已经在一棵树上");}else {if(tree[a1]<tree[b1])//这个是负数,为了简单减少计算,不在调用value函数{tree[a1]+=tree[b1];//个数相加  注意是负数相加tree[b1]=a1;       //b树成为a的子树,直接指向a;}else{tree[b1]+=tree[a1];//个数相加  注意是负数相加tree[a1]=b1;       //b树成为a的子树,直接指向a;}}}public static void main(String[] args){       DisjointSet d=new DisjointSet();d.union(1,2);d.union(3,4);d.union(5,6);d.union(1,6);d.union(22,24);d.union(3,26);d.union(36,24);System.out.println(d.search(6));    //头System.out.println(d.value(6));     //大小System.out.println(d.search(22));   //头System.out.println(d.value(22));     //大小}
}

结语

  • 并查集属于简单但是很高效率的数据结构。在集合中经常会遇到。如果不采用并查集而传统暴力效率太低,而不被采纳。
  • 另外,并查集还广泛用于迷宫游戏中,下面有机会可以介绍用并查集实现一个走迷宫小游戏。大家欢迎关注!

vb6实现union数据结构_数据结构与算法——并查集(不相交集合)相关推荐

  1. 数据结构与算法——并查集(不相交集合)

    文章目录 认识并查集 并查集解析 基本思想 如何查看a,b是否在一个集合? a,b合并,究竟是a的祖先合并在b的祖先上,还是b的祖先合并在a上? 其他路径压缩? 代码实现 结语 认识并查集 对于并查集 ...

  2. 【数据结构笔记17】集合的表示、双亲表示法、并查集、集合的并运算

    本次笔记内容: 5.3.1 集合的表示及查找 5.3.2 集合的并运算 文章目录 集合的表示 并查集 并查集问题中的存储实现 集合的并运算 直接实现的方法 Union函数更好的思想 集合的表示 集合的 ...

  3. UVA10034 Freckles【Kruskal算法+并查集】

    In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back to fo ...

  4. [基础算法] 并查集

    并查集 1.将两个集合合并 2.查询两个集合是否在同一个集合中 基本原理:每个集合用同一棵树来表示,树根的编号就是树的编号,每个节点储存其父节点,p[x]表示x的父节点. 问题一:如何判断是否为根节点 ...

  5. 算法导论之用于不相交集合的数据结构

    不相交集合,即集合内元素无交集.在一些具体应用中,需将n个不同的元素分成一组不相交的集合.不相交集合的两个重要操作,找出给定元素所属的集合和合并两个集合.为支持不相交集合的操作,需要设计和维护数据结构 ...

  6. 高级数据结构与算法 | 并查集(Union-Find)

    文章目录 并查集的原理 并查集的实现 例题 并查集的原理 在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合.开始时,每个元素自成一个 单元素集合,然后按一定的规律将归于同一组元素的集合合并 ...

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

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

  8. 基础数据结构(二):字典树、并查集、堆、哈希表、字符串的哈希方式、STL的常见容器及其接口

    文章目录 一.字典树Trie 1 原理 2 Trie字符串统计 3 [LeetCode 208. 实现 Trie (前缀树)](https://leetcode-cn.com/problems/imp ...

  9. 数据结构(八):并查集详解 (多图+动图)

    目录 一.什么是并查集 二.并查集的存储结构 三.并查集的基本操作 (一)初始化 (二)Find操作 (三)Union操作 四.并查集的优化 (一)Union操作优化(小树并入大树) (二)Find操 ...

最新文章

  1. 打通新场景,源创计划第一弹!“悟道”大模型应用合作交流会
  2. 如何测量OP-AMP的非线性?
  3. linux c 函数 link symlink unlink 链接相关功能
  4. AIX 添加开机启动项
  5. tmpfiles.d导致的unix:///tmp/supervisor.sock no such file坑(待续)
  6. 第69课 胡萝卜与骨头
  7. pku 1094(拓扑排序,多次拓扑)
  8. Java web ch02_3
  9. /etc/group
  10. toolchain安装教程支持_toolchain
  11. FreeBSD安装与配置(转)
  12. ubuntu查看端口
  13. 张钹院士:迈向第三代人工智能 |论文学习总结
  14. Netflix-Eureka服务注册与发现说明文档
  15. 数据字典的作用和定义(软件工程)
  16. Minio过期分片上传文件清理引出的系统配置
  17. 数据结构实验教程-第一套
  18. 广域虚拟数据空间中边缘缓存系统的研究与实现
  19. 网页制作常用html代码
  20. emmet之css语法_使用Emmet加快HTML和CSS的生产

热门文章

  1. scrapy mysql 报错_scrapy爬数据存mysql报错
  2. python从低到高排序_使用python对matplotlib直方图中的xaxis值从最低值到最高值排序...
  3. mysql 回收空间_MySQL表的碎片整理和空间回收小结
  4. php中文网地址多少,计算机网络中有几种地址格式
  5. python的垃圾回收机制和析构函数__del__
  6. python如何获取多个excel单元格的值
  7. 南农计算机分数线,南京农业大学
  8. 【opencv4】opencv视频教程 C++ 7、手动调整图像亮度与对比度 g(i, j) = αf(i, j) + β(点操作与邻域操作概念)
  9. python numpy hstack() from shape_base.py (将数组水平堆叠)
  10. 初学__Python——Python的流程控制语句 if、for、while