C++ 实现带路径压缩并查集算法优化思路判定逻辑源码实现【源码】

酷芳小哥_1750

酷芳小哥_1750

2026-05-24

498人浏览

原创

并查集优化有五种方法:一、递归路径压缩+按秩合并;二、迭代路径压缩+按大小启发式合并;三、懒惰单层压缩;四、模板化键类型支持;五、断言驱动的压缩有效性验证。

c++ 实现带路径压缩并查集算法优化思路判定逻辑源码实现【源码】

如果您在实现 C++ 并查集(Union-Find)结构时发现路径压缩未生效、合并逻辑错误或 find 操作时间退化,可能是由于压缩时机不当、递归/迭代实现缺陷或 union 判定条件误用。以下是几种可独立验证的优化思路与对应源码实现:

一、递归路径压缩 + 按秩合并实现

该方法在 find 过程中通过递归回溯一次性将整条路径上的节点直接挂载到根节点下,同时 union 时依据秩(rank)较小树挂入较大树,避免树高增长过快。

1、定义并查集类,包含 parent 和 rank 数组,初始化每个节点父节点为自身,rank 初始化为 0。

2、find 函数采用递归:若 x 不是根,则执行 parent[x] = find(parent[x]),再返回 parent[x]。

3、unionSet 函数先 find(x) 和 find(y),若根不同,则比较 rank[rootX] 与 rank[rootY];秩小者根指向秩大者根;若相等,任选其一作为新根,并将其 rank 加 1。

二、迭代路径压缩 + 启发式合并实现

规避递归调用栈开销与潜在栈溢出风险,使用显式循环完成路径遍历与父指针重写;启发式合并不依赖秩数组,改用子树大小(size)作为合并依据,提升实际性能稳定性。

1、声明 parent 和 size 数组,初始化 size[i] = 1。

2、find 函数使用 while 循环定位根节点,再用第二轮循环将路径上所有节点的 parent 直接设为根。

3、unionSet 中先获取两节点根,若不同,将 size 较小的根的 parent 设为 size 较大的根,并更新后者 size 值。

三、带压缩标记的懒惰路径压缩实现

适用于大规模动态图且 find 调用频次远高于 union 的场景,仅在 find 返回前对当前查询路径做单层压缩(即只将 x 的父节点设为父节点的父节点),不立即递归到底,降低单次 find 开销,后续多次访问自然收敛。

1、find 函数内不递归,仅判断 parent[x] != parent[parent[x]] 时执行 parent[x] = parent[parent[x]]。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

2、重复执行该跳转操作直至 parent[x] == parent[parent[x]] 或 parent[x] == x。

3、unionSet 保持基础版本:直接令 parent[rootX] = rootY,不做秩或大小判断。

四、模板化支持任意键类型的并查集封装

突破 int 索引限制,通过 std::map 或 std::unordered_map 映射键值到内部整型 ID,使字符串、pair 等类型可直接参与并查集操作,同时维持路径压缩有效性。

1、维护 map keyToId 与 vector parent,idCounter 记录已分配 ID 总数。

2、find(const Key& k) 先 ensureId(k) 分配 ID,再对对应 id 执行标准递归路径压缩 find(id)。

3、unionSet(const Key& a, const Key& b) 转换为对应 id 后调用整型 unionSet,ensureId 必须在每次 find/union 前调用以保证 ID 存在。

五、断言驱动的压缩有效性验证模块

在调试模式下插入运行时检查,确保每次 find 后路径长度 ≤ 2,且根节点 parent[root] == root,用于判定路径压缩是否真正生效而非逻辑空转。

1、定义 validatePathLength(int x) 函数,沿 parent 链计数至根,若长度 > 2 则 assert(false)。

2、在 find 返回前调用该验证函数,仅在 _DEBUG 或 ENABLE_VALIDATION 宏定义时启用。

3、添加 printTreeStructure() 辅助函数,输出每个节点的深度与父节点,供人工比对压缩前后差异。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2268

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习