C++ 代码实例:并查集简单创建工具

文章目录

  • 前言
  • 代码仓库
  • 代码
    • 说明
    • main.cpp
    • Makefile
  • 结果
  • 总结
  • 参考资料
  • 作者的话

前言

C++ 代码实例:并查集简单创建工具。


代码仓库

  • yezhening/Programming-examples: 编程实例 (github.com)
  • Programming-examples: 编程实例 (gitee.com)

代码

说明

  • 简单地创建并查集
  • 注释有详细的步骤解析
  • 还可优化的点:使用cmake;使用右值传递复杂容器减小开销

注:半个晚上完成,大概测试了下


main.cpp

#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>using std::cout;
using std::endl;
using std::pair;
using std::sort;
using std::unordered_map;
using std::vector;// 并查集类
class DisjointSet
{
public:// 构造并查集// 参数:等价关系元素值的大小/范围,等价关系集合向量DisjointSet(const int &e_q_s, const vector<pair<int, int>> &e_r_v) : eq_rel_size(e_q_s), eq_rel_vec(e_r_v){// 1. 初始化元素父节点向量,大小是等价关系元素值的大小/范围,每个元素的父节点约定为自身this->parent_vec.resize(this->eq_rel_size); // 元素父节点的向量的大小是等价关系元素值的大小/范围for (int i = 0; i < this->eq_rel_size; ++i){parent_vec[i] = i;}// 2. 初始化元素深度向量,大小是等价关系元素值的大小/范围,每个元素作为根节点约定为0即第0层// 合并操作依据树的深度优化,即优先将深度大的树的根挂接到深度小的树的根this->depth_vec.resize(this->eq_rel_size, 0);// 3. 按照字典序排序等价关系集合向量sort(this->eq_rel_vec.begin(), this->eq_rel_vec.end());// 4. 合并集合for (const auto &eq_rel_pair : eq_rel_vec) // 对每一个等价关系集合,如:{1, 2}{// 4.1 分别查找两关系元素的根节点int first_root = this->find_parent(eq_rel_pair.first);int second_root = this->find_parent(eq_rel_pair.second);// 4.2 依据根节点情况合并挂接if (first_root == second_root) // 相等不操作{continue;}else // first_root != second_root{if (this->depth_vec[first_root] < this->depth_vec[second_root]) // 优先将深度大的树的根挂接到深度小的树的根{this->parent_vec[first_root] = second_root;}else if (this->depth_vec[first_root] > this->depth_vec[second_root]){this->parent_vec[second_root] = first_root;}else // == 树的深度相等,约定将第二个根挂接到第一个根,第一个根的深度加深一层{this->parent_vec[second_root] = first_root;++this->depth_vec[first_root];}}}// 5. 构建结果unordered_map<int, vector<int>> root_vec{}; // 哈希表,记录 根节点值-该根节点下的元素向量,一个向量是一棵新树for (int i = 0; i < this->eq_rel_size; ++i) // 遍历元素值{int root = this->find_parent(i); // 取根节点root_vec[root].push_back(i);}for (const pair<int, vector<int>> &pair_tree : root_vec) // 遍历每棵树,加入到结果集{this->disjoint_set.insert(this->disjoint_set.begin(), pair_tree.second);}}// 获取并查集inline vector<vector<int>> get_disjoint_set() const{return this->disjoint_set;}// 打印并查集inline void print_disjoint_set() const{cout << "并查集: " << endl;for (const vector<int> set : this->disjoint_set){for (const int num : set){cout << num << " ";}cout << endl;}return;}private:const int eq_rel_size;             // 等价关系元素值的大小/范围vector<pair<int, int>> eq_rel_vec; // 等价关系集合向量vector<int> parent_vec; // 记录元素父节点的向量vector<int> depth_vec;  // 记录元素深度的向量,约定元素值/树的根是索引,根的深度从0、1往上加vector<vector<int>> disjoint_set; // 并查集,并查集类固有的本质内容// 递归查找当前元素值的根节点int find_parent(int x){// 1. 递归逻辑// 如果不是,parent[x] != x,则使用当前节点的父节点作为参数,调用当前函数,递归继续找爷节点:find_parent(parent[x])// 把找到的根节点记录在查找路径中每个节点的 元素父节点的向量 中:parent_vec[x] =// 相当于把该些节点,都挂接到根节点上,树变得扁平// 即路径压缩优化:在并查集中,每个元素都有一个父节点,通常在查找操作中,我们会沿着父节点链一直向上找到根节点// 这个过程就是在寻找元素所在集合的过程。但是,在普通的查找操作中,路径的长度可能会很长,导致后续的查找操作效率较低。// 路径压缩是一种优化技术,它的思想是:当我们在进行查找操作时,不仅找到元素所在集合的根节点,// 还顺便将经过的所有节点的父节点都设置为根节点。这样,当下次再次查找这些节点时,路径就会更短,查找效率就会更高。// 如:1为根节点,23为子节点,有1 - 2 - 3的三层树,从叶节点3开始找,找到1根节点,然后依次递归返回把2、3的根节点设置为1// 成为1 - 2,1 - 3的两层树if (parent_vec[x] != x){parent_vec[x] = find_parent(parent_vec[x]);}// 1. 递归出口// 如果x的父节点是自己,说明它是根节点,返回// parent_vec[x] == x// 把return放在if会有到不了该条件if的警告:control reaches end of non-void function [-Wreturn-type]return parent_vec[x];}
};int main()
{const int eq_rel_size = 9;                                                                          // 等价关系元素值的大小/范围const vector<pair<int, int>> eq_rel_vec = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {0, 2}, {4, 6}, {0, 8}}; // 等价关系集合向量,内容必须是0~ eq_rel_size - 1(并查集类的逻辑定义了)DisjointSet ds(eq_rel_size, eq_rel_vec); // 并查集对象ds.print_disjoint_set();                 // 打印并查集return 0;
}

Makefile

.PHONY : all
all : main.exemain.exe : main.cppg++ -o $@ $^.PHONY : clean
clean :del *.exe

结果

在这里插入图片描述


总结

C++ 代码实例:并查集简单创建工具。


参考资料

  • 学校《高级算法设计与分析》课程课件的算法思路

作者的话

  • 感谢参考资料的作者/博主
  • 作者:夜悊
  • 版权所有,转载请注明出处,谢谢~
  • 如果文章对你有帮助,请点个赞或加个粉丝吧,你的支持就是作者的动力~
  • 文章在描述时有疑惑的地方,请留言,定会一一耐心讨论、解答
  • 文章在认识上有错误的地方, 敬请批评指正
  • 望读者们都能有所收获

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/161688.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

<Vue>使用依赖注入的方式共享数据

什么是vue依赖注入&#xff1f; Vue是一个用于构建用户界面的渐进式框架。 它提供了一种简单而灵活的方式来管理组件之间的数据流&#xff0c;即依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;。 依赖注入是一种设计模式&#xff0c;它允许一个组件从另一…

HTTPS的加密方式超详细解读

在了解https的加密方式之前&#xff0c;我们需要先行了解两个特别经典的传统加密方式&#xff1a; 1、对称加密 1.1、定义 需要对加密和解密使用相同密钥的加密算法。所谓对称&#xff0c;就是采用这种加密方法的双方使用方式用同样的密钥进行加密和解密。密钥是控制加密及解…

【技术干货】开源库 Com.Gitusme.Net.Extensiones.Core 的使用

目录 1、项目介绍 2、为项目添加依赖 3、代码中导入命名空间 4、代码中使用 示例 1&#xff1a;string转换 示例 2&#xff1a;object转换 1、项目介绍 Com.Gitusme.Net.Extensiones.Core是一个.Net扩展库。当前最新版本1.0.4&#xff0c;提供了常见类型转换&#xff0c…

<蓝桥杯软件赛>零基础备赛20周--第4周--杂题-1

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周&#xff08;读者可以按…

统计学习方法 条件随机场

文章目录 统计学习方法 条件随机场随机场马尔可夫随机场定义因子分解 条件随机场定义参数化形式简化形式矩阵形式 概率预测问题前向-后向算法概率的计算期望值的计算 学习问题改进的迭代尺度法拟牛顿法 解码问题 统计学习方法 条件随机场 学习李航的《统计学习方法》时&#x…

ok-解决qt5发布版本,直接运行exe缺少各种库的问题

已实验第二种方法可用。 工具&#xff1a;电脑必备、QT下的windeployqt Qt 官方开发环境使用的动态链接库方式&#xff0c;在发布生成的exe程序时&#xff0c;需要复制一大堆 dll&#xff0c;如果自己去复制dll&#xff0c;很可能丢三落四&#xff0c;导致exe在别的电脑里无法…

C++11 智能指针学习笔记

非常棒的学习博客 在C中没有垃圾回收机制&#xff0c;必须自己释放分配的内存&#xff0c;否则就会造成内存泄露。 1. shared_ptr 共享智能指针是指多个智能指针可以同时管理同一块有效的内存&#xff0c;共享智能指针 shared_ptr 是一个模板类。智能指针的核心实现技术是引用…

Framebuffer 介绍和应用编程

前言&#xff1a; 使用的开发板为韦东山老师的 IMX6ULL 目录 Framebuffer介绍 LCD 操作原理 涉及的 API 函数 1.open 函数 2.ioctl 函数 3.mmap 函数 Framebuffer 程序分析 1.打开设备 2.获取 LCD 参数 3.映射 Framebuffer 4.描点函数 5.随便画几个点 6.上机实验…

[vmware]vmware虚拟机压缩空间清理空间

vmware中的ubuntu使用如果拷贝文件进去在删除&#xff0c;vmare镜像文件并不会减少日积月累会不断是的真实物理磁盘空间大幅度减少&#xff0c;比如我以前windows操作系统本来只有30GB最后居然占道硬盘200GB&#xff0c;清理方法有2种。 第一种&#xff1a;vmware界面操作 第二…

Lamport Clock算法

Lamport Clock 是一种表达逻辑时间的逻辑时钟&#xff08;logical clock&#xff09;&#xff0c;能够计算得到历史事件的时间偏序关系。 假设 P0进程是分布式集群中心节点中的监控者&#xff0c;用于统一管理分布式系统中事件的顺序。其他进程在发送消息之前和接受事件消息之后…

持续进化,快速转录,Faster-Whisper对视频进行双语字幕转录实践(Python3.10)

Faster-Whisper是Whisper开源后的第三方进化版本&#xff0c;它对原始的 Whisper 模型结构进行了改进和优化。这包括减少模型的层数、减少参数量、简化模型结构等&#xff0c;从而减少了计算量和内存消耗&#xff0c;提高了推理速度&#xff0c;与此同时&#xff0c;Faster-Whi…

包装印刷行业万界星空科技云MES解决方案

印刷业的机械化程度在国内制造行业内算是比较高的&#xff0c;不算是劳动密集型企业。如书本的装订、包装的模切、烫金、糊盒等都已经有了全自动设备。印刷厂除了部分手工必须采用人工外&#xff0c;大部分都可以采用机器&#xff0c;也就意味着可以由少量工人生产出大量产品。…