【算法与数据结构】—— 并查集

【算法与数据结构】—— 并查集并查集概念 并查集由一个整型数组 pre 和两个函数 find join 构成数组 pre 记录了每个点的前导点是什么 函数 find 用于查找 函数 join x y 用于合并作用 并查集的主要作用是求连通分支数 如果一个图中所有点都存在可达关系 直接或间接相连 则此图的连通分支数为 1 如果此图有两大子图各自全部可达 则此图的连通分支数为 2 问题引入话说江湖上散落

并查集


1. 概论


2. 并查集的现实意义


3. find( )函数的定义与实现

int find(int x) //查找x的教主 { 
            while(pre[x] != x) //如果x的上级不是自己(则说明找到的人不是教主) x = pre[x]; //x继续找他的上级,直到找到教主为止 return x; //教主驾到~~~ } 


4. join( )函数的定义与实现

void join(int x,int y) //我想让虚竹和周芷若做朋友 { 
               int fx=find(x), fy=find(y); //虚竹的老大是玄慈,芷若MM的老大是灭绝 if(fx != fy) //玄慈和灭绝显然不是同一个人 pre[fx]=fy; //方丈只好委委屈屈地当了师太的手下啦 } 


5. 路径压缩算法之一(优化find( )函数)

if(fx != fy) pre[fx]=fy; 
int find(int x) //查找结点 x的根结点  { 
                  if(pre[x] == x) return x; //递归出口:x的上级为 x本身,即 x为根结点  return pre[x] = find(pre[x]); //此代码相当于先找到根结点 rootx,然后pre[x]=rootx  } 

该算法存在一个缺陷:只有当查找了某个节点的代表元(教主)后,才能对该查找路径上的各节点进行路径压缩。换言之,第一次执行查找操作的时候是实现没有压缩效果的,只有在之后才有效。


6. 路径压缩算法之二(加权标记法)

void union(int x,int y) { 
                     x=find(x); //寻找 x的代表元 y=find(y); //寻找 y的代表元 if(x==y) return ; //如果 x和 y的代表元一致,说明他们共属同一集合,则不需要合并,直接返回;否则,执行下面的逻辑 if(rank[x]>rank[y]) pre[y]=x; //如果 x的高度大于 y,则令 y的上级为 x else //否则 { 
                     if(rank[x]==rank[y]) rank[y]++; //如果 x的高度和 y的高度相同,则令 y的高度加1 pre[x]=y; //让 x的上级为 y } } 


7. 总结

下面给出上述所有内容的代码汇总:

const int N=1005 //指定并查集所能包含元素的个数(由题意决定) int pre[N]; //存储每个结点的前驱结点  int rank[N]; //树的高度  void init(int n) //初始化函数,对录入的 n个结点进行初始化  { 
                          for(int i = 0; i < n; i++){ 
                          pre[i] = i; //每个结点的上级都是自己  rank[i] = 1; //每个结点构成的树的高度为 1  } } int find(int x) //查找结点 x的根结点  { 
                          if(pre[x] == x) return x; //递归出口:x的上级为 x本身,则 x为根结点  return find(pre[x]); //递归查找  } int find(int x) //改进查找算法:完成路径压缩,将 x的上级直接变为根结点,那么树的高度就会大大降低  { 
                          if(pre[x] == x) return x; //递归出口:x的上级为 x本身,即 x为根结点  return pre[x] = find(pre[x]); //此代码相当于先找到根结点 rootx,然后 pre[x]=rootx  } bool isSame(int x, int y) //判断两个结点是否连通  { 
                          return find(x) == find(y); //判断两个结点的根结点(即代表元)是否相同  } bool join(int x,int y) { 
                          x = find(x); //寻找 x的代表元 y = find(y); //寻找 y的代表元 if(x == y) return false; //如果 x和 y的代表元一致,说明他们共属同一集合,则不需要合并,返回 false,表示合并失败;否则,执行下面的逻辑 if(rank[x] > rank[y]) pre[y]=x; //如果 x的高度大于 y,则令 y的上级为 x else //否则 { 
                          if(rank[x]==rank[y]) rank[y]++; //如果 x的高度和 y的高度相同,则令 y的高度加1 pre[x]=y; //让 x的上级为 y } return true; //返回 true,表示合并成功 } 
















































版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/199534.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月20日 下午12:47
下一篇 2026年3月20日 下午12:47


相关推荐

  • shell 编译和执行java文件

    shell 编译和执行java文件

    2022年2月5日
    46
  • mount 命令介绍

    mount 命令介绍磁盘挂载可以有效解决数据同步与磁盘空间浪费的问题 而且支持不同操作系统之间挂载操作 核心命令为 mount 本文介绍该命令 挂载挂载常用的命令为 mount 其命令格式为 mount args devicedirarg 表示配置参数 其中最常用的为 t 和 o 参数 t 指定文件系统的类型 通常不必指定 mount 会自动选择正确的类型 常用类型有 iso9660 光盘或光盘镜像 msdos DOSfat16 文件系统 vfat Windows9xfat 文件系统 n

    2025年7月11日
    7
  • Nginx(三):负载均衡策略 与 Nginx静态服务器

    Nginx(三):负载均衡策略 与 Nginx静态服务器

    2021年10月5日
    31
  • 广东电信最新DNS更新了[通俗易懂]

    广东电信最新DNS更新了[通俗易懂]原来广东电信最新dns更新了!记录一下,方便以后查找!运行超过10年时间的广东地区骨干dns域名服务器系统:202.96.128.68,因严重超负荷运作多年,从12月3日开始正式迁移,共分一个月时间,全省范围内的电信用户(包括宽、窄带、专线用户)将采用新的域名服务器。中国电信广州用户“首选dns服务器”为:61.144.56.100“备用dns服务器”为:61.144.56.101中…

    2022年7月11日
    60
  • Python 爬虫是什么

    Python 爬虫是什么作为程序员 相信大家对 爬虫 这个词并不陌生 身边常常会有人提这个词 在不了解它的人眼中 会觉得这个技术很高端很神秘 不用着急 我们的爬虫系列就是带你去揭开它的神秘面纱 探寻它真实的面目 爬虫是什么网络爬虫 又被称为网页蜘蛛 网络机器人 是一种按照一定的规则 自动地抓取万维网信息的程序或者脚本 另外一些不常使用的名字还有蚂蚁 自动索引 模拟程序或者蠕虫 通俗地讲 我们把

    2026年3月16日
    2
  • 【深入Java虚拟机】之四:类加载机制

    【深入Java虚拟机】之四:类加载机制类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。在这五个阶段中,加载、验证、准备和初始化这四个阶段发生的顺序是确定的,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行

    2022年5月24日
    30

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号