【数据结构】[特殊字符] 并查集优化全解:从链式退化到近O(1)的性能飞跃 | 路径压缩与合并策略深度实战
并查集的优化
- 导读
- 一、合并优化
- 1.1 基本原理
- 1.2 按大小合并
- 1.3 按秩合并
- 1.4 两种合并的区别
- **1.4.1 核心目标**
- **1.4.2 数据存储**
- **1.4.3 合并逻辑**
- **1.4.4 树高控制**
- **1.4.5 适用场景**
- **1.4.6 路径压缩兼容性**
- **1.4.7 极端案例对比**
- **1.4.8 小结**
- 二、查找优化
- 2.1 路径压缩
- 2.2 算法实现
- 三、算法评估
- 3.1**时间复杂度**
- 3.1.1 **按大小合并(Union by Size)**
- 3.1.2 **按秩合并(Union by Rank)**
- 3.1.3 **路径压缩(Path Compression)**
- 3.2 **空间复杂度**
- 3.2.1 **按大小合并**
- 3.2.2 **按秩合并**
- 3.2.3 **路径压缩**
- 3.3 **优化策略的协同作用**
- 3.3.1 **按大小合并 + 路径压缩**
- 3.3.2 **按秩合并 + 路径压缩**
- 3.4 **极端场景示例**
- 3.4.1 **按大小合并**
- 3.4.2 **按秩合并**
- 3.5 小结
- 🚀 结语:并查集优化——效率与智慧的结晶
- 🔍 **核心优化回顾**
- ⏱️ **时间复杂度突破**
- 🧩 **优化策略对比与选择**
- 💡 **实战启示**
- 🌟 **下篇预告**

导读
大家好,很高兴又和大家见面啦!!!
在上一篇内容中我们正确认识了并查集,并通过数据元素与其双亲指针的映射关系实现了并查集的查找与合并的。
但是上一篇的算法实现中,算法的最坏时间复杂度可以达到 O ( N ) O(N) O(N),这并不能很好的满足高效处理动态连通性问题。
在今天的内容中,我们将通过路径优化与按秩合并两种优化方式对并查集实现进一步的优化,大大提高处理动态连通性的效率。
一、合并优化
在并查集中,影响其时间复杂度的操作在查找上,而树的高度h是影响查找时间复杂度的重要因素。那么我们要对并查集的算法进行优化,那就得从树高下手。
下面我们就来看一下如何通过优化不同子集的合并从而优化整个并查集的算法。
1.1 基本原理
当两个树高不同的子集进行合并时,会存在两种合并方案:
- 小树合并到大树
- 大树合并到小树

不难发现,当大树将小树合并时并不会影响大树的树高,但是当小树将大树合并时,则会增加树高。
试想一下,如果我们要完成n棵树的合并,如果将n-1棵小树合并到大树上,这样我们就能保证在进行查找时,能够尽可能的降低查找时间复杂度。
但是当我们在进行合并时,是将大树合并到小树上,则会不断地增加树高,这样每一次合并,都会增加查找的时间复杂度。
因此为了尽可能优化并查集,那么我们在进行合并操作时,应该在每一次合并操作时,都保证是小树合并到大树上。
今天我们介绍两种优化方案——按大小合并、按秩合并。
1.2 按大小合并
按大小合并指的是根据树的大小,将小树合并到大树。
树的大小由树的结点数量决定,结点多的树为大树,结点少的树为小数。通过树的根结点的绝对值表示树的大小。
这里我们以大写字符为例,我们通过一个整型数组parent来存放每个元素的双亲位置信息:

该算法的实现比较简单,我们只需要在合并算法中加入一个对根结点大小的判断,并且在完成合并后,修改根结点的值:
//按大小合并优化
void Union_by_Size(DSU* s, int root1, int root2) {if (root1 != root2) {//根结点为负数,值越大,结点数量越少if (s->parent[root1] > s->parent[root2]) {s->parent[root2] += s->parent[root1];//修改大树根结点s->parent[root1] = root2;//修改小树根结点}else {s->parent[root1] += s->parent[root2];s->parent[root2] = root1;}}
}
通过按大小合并的方式优化,可以极大可能的降低合并后的树高,但是也不一定。
比如结点多但高度低的大树与结点少但高度高的小树进行合并,此时如果按照大小来进行合并,则会增加合并后树的高度。
那有没有不会影响高度的优化方式呢?这就是我们接下来要介绍的按秩合并;
1.3 按秩合并
所谓的秩(Rank)代表的是树合并前的最大高度。
按秩合并实际上就是根据树高进行合并,将矮树合并到高树中,从而确保在完成合并后的树高最小。
合并的规则如下:
- 所有结点的初始高度为0,即根结点的高度为0
- 将秩小的树合并到秩大的树下,秩保持不变
- 将秩相同的两棵树进行合并,合并后,根结点的秩加1
在按秩合并中,我们需要维护两个数组:
- parent数组——记录结点的双亲位置
- rank数组——记录根结点的秩
对应的实现也很简单,如下所示:
//按秩合并
void Union_by_Rank(DSU* s, int root1, int root2) {if (root1 != root2) {if (s->rank[root1] > s->rank[root2]) {s->parent[root2] = root1;//低秩合并到高秩中}else {s->parent[root1] = root2;if (s->rank[root1] == s->rank[root2]) {s->rank[root2] 相关文章:
【数据结构】[特殊字符] 并查集优化全解:从链式退化到近O(1)的性能飞跃 | 路径压缩与合并策略深度实战
并查集的优化 导读一、合并优化1.1 基本原理1.2 按大小合并1.3 按秩合并1.4 两种合并的区别**1.4.1 核心目标****1.4.2 数据存储****1.4.3 合并逻辑****1.4.4 树高控制****1.4.5 适用场景****1.4.6 路径压缩兼容性****1.4.7 极端案例对比****1.4.8 小结**二、查找优化2.1 路径压…...
如何在 AI 搜索引擎(GEO)霸屏曝光,快速提升知名度?
虽然大多数人仍然使用 Google 来寻找答案,但正在发生快速转变。ChatGPT、Copilot、Perplexity 和 DeepSeek 等 LLM 已成为主流。这主要是因为每个都有自己的免费和公共版本,并且总是有重大的质量改进。 许多人每天都使用这些工具来提问和搜索互联网&…...
VLAN综合实验二
一.实验拓扑: 二.实验需求: 1.内网Ip地址使用172.16.0.0/分配 2.sw1和SW2之间互为备份 3.VRRP/STP/VLAN/Eth-trunk均使用 4.所有Pc均通过DHCP获取IP地址 5.ISP只能配置IP地址 6.所有…...
Kubernetes》k8s》Containerd 、ctr 、cri、crictl
containerd ctr crictl ctr 是 containerd 的一个客户端工具。 crictl 是 CRI 兼容的容器运行时命令行接口,可以使用它来检查和调试 k8s 节点上的容器运行时和应用程序。 ctr -v 输出的是 containerd 的版本, crictl -v 输出的是当前 k8s 的版本&#x…...
SQL语句及其应用(中)(DQL语句之单表查询)
SQL语句的定义: 概述: 全称叫 Structured Query Language, 结构化查询语言, 主要是实现 用户(程序员) 和 数据库软件(例如: MySQL, Oracle)之间交互用的. 分类: DDL: 数据定义语言, 主要是操作 数据库, 数据表, 字段, 进行: 增删改查(CURD) 涉及到的关键字: create, drop, …...
如何下载主流网站的视频和音频?(支持100+网站视频下载)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、安装与升级1. 安装2. 升级到最新版3. 验证安装二、基础下载命令1. 下载视频/音频/图片2. 指定下载目录3. 自定义文件名4. 基本下载场景三、高级下载控制1. 查看视频信息(清晰度/格式)2. 选择特定清晰度下载3. 下载…...
算法题(111):k与迷宫
审题: 本题需要我们寻找迷宫中的所有出口,若有出口需要输出距离最近的出口的距离,若没有就输出-1 时间复杂度:由于边距为1,我们本题采用bfs算法,在最坏的情况下我们需要遍历所有位置,时间复杂度…...
WinForm真入门-简介
WinForm 简介 WinForm(Windows Forms)是微软基于 .NET Framework 构建的桌面应用程序开发框架,专注于快速创建具有图形用户界面(GUI)的 Windows 客户端程序。其核心以 窗体(Form)…...
Java 求两个 List 集合的交集和差集
目录 一、求两个 List 的交集(一)使用 Java 8 Stream API(二)运行结果(三)技术亮点(四)适用场景二、求两个 List 的差集(一)使用 Java 8 Stream API(二)运行结果(三)技术亮点(四)适用场景三、使用传统迭代方法(一)求交集(二)求差集(三)运行结果(四)技术…...
Redis-常用命令
目录 1、Redis数据结构 2、命令简介 2.1、通用命令 DEL EXISTS EXPIRE 2.2、String命令 SET和GET MSET和MGET INCR和INCRBY和DECY SETNX SETEX 2.3、Key的层级结构 2.4、Hash命令 HSET和HGET HMSET和HMGET HGETALL HKEYS和HVALS HINCRBY HSETNX 2.5、List命…...
树莓派5智能家居中控:HomeAssistant全配置指南
一、硬件选型与系统架构 1.1 树莓派5的硬件优势 2023年发布的树莓派5采用Broadcom BCM2712处理器(4核Cortex-A76架构),相比前代产品具有三大突破性改进: 接口升级:首次支持PCIe 2.0接口,可扩展万兆网卡或…...
从虚拟现实到可持续设计:唐婉歆的多维创新之旅
随着线上线下融合逐渐成为全球家居与建材行业的发展趋势,全球市场对高品质、个性化家居和建材产品的需求稳步攀升,也对设计师提出更高的要求。在这一背景下,设计师唐婉歆将以产品设计师的身份,正式加入跨国企业AmCan 美加集团,投身于备受行业瞩目的系列设计项目。她将负责Showr…...
scala基础学习-类(1.定义类)
文章目录 类,对象定义类构造定义方法重写方法私有默认参数 类,对象 scala定义类的关键字是:class 使用类实例化对象使用关键字:new 定义类 class Point(var x: Int, var y: Int) {def move(dx: Int, dy: Int): Unit {x x dxy y dy}override def…...
音视频 四 看书的笔记 MediaPlayerService
Binder机制看这里 Binde机智 这是一个分割符 Binder机智 分割(goutou) Binder机制 MediaPlayerService多媒体框架中一个非常重要的服务。MediaPlayerService 我原称之为链接之王 图片来源 MediaPlayer 是客户端 C/S 中的CMediaPlayerService MediaPlayerService::Client 是服…...
vmware 创建win10 系统,虚拟机NAT网络设置
虚拟机设置: 物理机本机创建桥接: 如何创建桥接,请自行脑补~...
Python CSV 数据分析:问题排查与解决全记录
Python CSV 数据分析:问题排查与解决全记录 前段时间,我接到一个任务,需要对公司的销售数据进行分析。这些数据存储在 CSV 文件里,本想着用 Python 处理起来会很轻松,结果却状况百出。下面,就跟大家讲讲我…...
RabbitMQ高级特性--发送方确认
目录 1. confirm确认模式 1.配置RabbitMQ 2.设置确认回调逻辑并发送消息 2.Return退回模式 1.配置RabbitMQ 2.设置返回回调逻辑并发送消息 在使用RabbitMQ的时候, 可以通过消息持久化来解决因为服务器的异常崩溃而导致的消息丢失, 但是还有⼀个问题, 当消息的生产者将消息发送出…...
【初阶数据结构】线性表之双链表
文章目录 目录 一、双链表的概念 二、双链表的实现 1.初始化 2.尾插 3.头插 4.打印 5.判断双链表是否为空 6.尾删 7.头删 8.查找 9.在指定的位置之后插入数据 10.删除指定位置的数据 11.销毁 三、完整源码 总结 一、双链表的概念 链表的结构非常多样࿰…...
java网盘项目 目前 文件有分享表 文件夹也要创建分享表吗
java网盘项目 目前 文件有分享表 文件夹也要创建分享表吗 根据网盘系统的典型设计模式及搜索结果中的最佳实践,建议为文件夹创建独立的分享表。以下是具体分析及实施建议: 一、需要独立文件夹分享表的核心原因 权限控制差异 文件分享:通常基…...
智能路由系统-信息泄露漏洞挖掘
1.漏洞描述: Secnet-智能路由系统 actpt_5g.data 信息泄露,攻击者可利用此漏洞收集敏感信息,从而为下一步攻击做准备。 2.fofa搜索语句 title"安网-智能路由系统" || title"智能路由系统" || title"安网科技-智能…...
表格图表切换,图表无法展示问题复盘
项目背景 103项目CPC卡使用模块在原有的表格展示数据的基础之上,增加环状饼图图表展示,采用tab切换的方式实现 问题描述 图表无法设置宽高,导致饼图无法渲染 具体代码 // 入口页<el-tabs type"card" class"cts_flex_t…...
css 实现闪烁光标
要实现闪烁光标(比如文本输入框内常见的闪烁效果),可以使用 CSS 动画。下面是一个简单的方法: 代码示例 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta n…...
AI赋能python数据处理、分析与预测操作流程
以数据集预测鱼类种类(Species)开展以下研究。数据格式如下: 以下是一个系统的分析思路及推荐的机器学习算法: 1. 数据预处理与探索性分析 缺失值与异常值处理: 检查数据完整性(如Roach类中Weight=0的记录需修正或删除)。 通过箱线图或Z-Score检测异常值,判断是否需…...
基于74LS192的十进制两位数正向计时器(proteus仿真)
在数字电路设计中,计时器是一个非常常见的应用。今天,我将分享一个基于 74LS192 双向计数器 的十进制两位数正向计时器电路设计。这个电路可以实现从 00 到 99 的十进制正向计数,并通过两个七段数码管显示结果。 最终效果如图: 各…...
#C8# UVM中的factory机制 #S8.5# 对factory机制的重载进一步思考(二)
今天我们反思,然后总结。 一 先看代码 `timescale 1ns/1ps module tb_top;class Base;function void print(int a);$display("Base: int = %0d", a);endfunction endclassclass Sub extends Base;function void print(string s);$display("Sub: string = %s&…...
算法-前缀和与差分
一、前缀和(Prefix Sum) 1. 核心思想 前缀和是一种预处理数组的方法,通过预先计算并存储数组的前缀和,使得后续的区间和查询可以在**O(1)**时间内完成。 2. 定义 给定数组 nums,前缀和数组 prefixSum 的每个元素 p…...
React(六)React过渡动画-CSS编写方式
React过渡动画 react-transition-group介绍 在开发中,我们想要给一个组件的显示和消失添加某种过渡动画,提高用户体验→可通过react-transition-group实现。React曾为开发者提供过动画插件 react-addons-css-transition-group,后由社区维护…...
第十五章:Python的Pandas库详解及常见用法
在数据分析领域,Python的Pandas库是一个不可或缺的工具。它提供了高效的数据结构和数据分析工具,使得数据处理变得简单而直观。本文将详细介绍Pandas库的基本功能、常见用法,并通过示例代码演示如何使用Pandas进行数据处理。最后,…...
Python自动化模块:开启高效编程新时代
一、写在前面 在数字化时代,自动化技术已成为提高效率、降低成本的关键手段。Python 作为一种简洁、高效且功能强大的编程语言,凭借其丰富的库和框架,在自动化领域占据了举足轻重的地位,成为众多开发者的首选工具之一。从简单的文…...
【蓝桥杯速成】| 15.完全背包
题目:携带研究材料 问题描述 52. 携带研究材料(第七期模拟笔试) 小明是一位科学家,他需要参加一场重要的国际科学大会,以展示自己的最新研究成果。他需要带一些研究材料,但是他的行李箱空间有限。这些研…...
