当前位置: 首页 > news >正文

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++ 代码实例:并查集简单创建工具。


参考资料

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

作者的话

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

相关文章:

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

文章目录 前言代码仓库代码说明main.cppMakefile 结果总结参考资料作者的话 前言 C 代码实例&#xff1a;并查集简单创建工具。 代码仓库 yezhening/Programming-examples: 编程实例 (github.com)Programming-examples: 编程实例 (gitee.com) 代码 说明 简单地创建并查集注…...

Hadoop学习总结(Shell操作)

HDFS Shell 参数 命令参数功能描述-ls查看指定路径的目录结构-du统计目录下所有文件大小-mv移动文件-cp复制文件-rm删除文件 / 空白文件夹-put上传文件-cat查看内容文件-text将源文件输出文本格式-mkdir创建空白文件夹-help帮助 一、ls 命令 ls 命令用于查看指定路径的当前目录…...

LeetCode热题100——链表

链表 1. 相交链表2. 反转链表3. 回文链表4. 环形链表5. 合并两个有序链表 1. 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 // 题解&#xff1a;使用A/B循环遍…...

使用C++的QT框架实现贪吃蛇

最近刷抖音经常看到别人使用类似chatGPT的al工具实现这个贪吃蛇游戏&#xff0c;正好我之前也写过&#xff0c;那么今天看看怎么去实现这个简单的游戏 我这边使用的是C的QT框架&#xff0c;当然用哪些框架都可以&#xff0c;主要是逻辑思路 1.生成画布&#xff0c;开始是一些…...

如何发布自己的golang库

如何发布自己的golang库 1、在 github/gitee 上创建一个 public 仓库&#xff0c;仓库名与 go 库名一致&#xff0c;然后将该仓库 clone 到本地。 本文这里使用 gitee。 $ git clone https://gitee.com/zsx242030/goutil.git2、进入项目文件夹&#xff0c;进行初始化。 $ go…...

梳理自动驾驶中的各类坐标系

目录 自动驾驶中的坐标系定义 关于坐标系的定义 几大常用坐标系 世界坐标系 自车坐标系 传感器坐标系 激光雷达坐标系 相机坐标系 如何理解坐标转换 机器人基础中的坐标转换概念 左乘右乘的概念 对左乘右乘的理解 再谈自动驾驶中的坐标转换 本节参考文献 自动驾驶…...

一个可以自动把微信聊天收到的二维码图片实时提取出来并分类的软件

10-1 如果你有需要实时地、自动地把微信各个群收到的二维码图片提取出来的需求&#xff0c;那本文章适合你&#xff0c;本文章的主要内容是教你如何实现自动提取微信收到的二维码图片&#xff0c;助你快速扫码&#xff0c;永远比别人领先一步。 首先需要准备好的材料&#xf…...

02-React组件与模块

组件与模块 前期准备 安装React官方浏览器调试工具&#xff0c;浏览器扩展搜索即可 比如红色的React就是本地开发模式 开启一个用React写的网站&#xff0c;比如美团 此时开发状态就变成了蓝色 组件也能解析出来 何为组件&模块 模块&#xff0c;简单来说就是JS代…...

项目实战:新增@RequestMapping和@GetMapping和@PostMapping三个注解

1、RequestMapping package com.csdn.mymvc.annotation; import java.lang.annotation.*; Target(ElementType.TYPE) Retention(RetentionPolicy.RUNTIME) Inherited public interface RequestMapping {String value(); }2、PostMapping package com.csdn.mymvc.annotation; im…...

基于AOSP源码Android-10.0.0_r41分支编译,framework开发,修改系统默认字体大小

文章目录 基于AOSP源码Android-10.0.0_r41分支编译&#xff0c;framework开发&#xff0c;修改系统默认字体大小 基于AOSP源码Android-10.0.0_r41分支编译&#xff0c;framework开发&#xff0c;修改系统默认字体大小 主要修改一个地方就行 代码源码路径 frameworks/base/co…...

如何再kali中下载iwebsec靶场

这个靶场有三种搭建方法&#xff1a; 第一种是在线靶场&#xff1a;http://www.iwebsec.com:81/ 第二种是虚拟机版本的&#xff0c;直接下载到本地搭建 官网地址下载&#xff1a;http://www.iwebsec.com/ 而第三种就是利用docker搭建这个靶场&#xff0c;我这里是用kali进行…...

Spring Boot 使用断言抛出自定义异常,优化异常处理机制

文章目录 什么是断言&#xff1f;什么是异常&#xff1f;基于断言实现的异常处理机制创建自定义异常类创建全局异常处理器创建自定义断言类创建响应码类创建工具类测试效果 什么是断言&#xff1f; 实际上&#xff0c;断言&#xff08;Assertion&#xff09;是在Java 1.4 版本…...

vue基于ElementUI/Plus自定义的一些组件

vue3-my-ElementPlus 源码请到GitHub下载使用MyTable、MySelect、MyPagination 置顶|Top | 使用案例&#xff1a; 1.0 定义表格数据&#xff08;测试使用&#xff09; data() {return {tableData: [],value:[],valueList: [],}; },// 构造表格测试数据// 1 第一行&#xf…...

leetcode刷题日记:69.sqrt(x)

给出一个非负的整数x&#xff0c;返回x的平方根向下取整的结果&#xff0c;这个被返回的数也应该是一个非负的值。 对我们的要求是不能使用任何内置的指数函数与操作&#xff0c;官方还给了我们例子&#xff1a; 在C种不能使用pow(x, 0.5) 在python不能使用 x**0.5 既然官方已经…...

[尚硅谷React笔记]——第9章 ReactRouter6

目录&#xff1a; 课程说明一级路由重定向NavLink高亮useRoutes路由表嵌套路由路由的params参数路由的search参数路由的state参数编程式路由导航useRouterContextuseNavigationTypeuseOutletuseResolvedPath()总结项目地址 1.课程说明 概述 React Router以三个不同的包发布…...

强大的pdf编辑软件:Acrobat Pro DC 2023中文

Acrobat Pro DC 2023是一款强大的PDF编辑和管理软件&#xff0c;它提供了广泛的功能&#xff0c;使用户能够轻松创建、编辑、转换和共享PDF文档。通过直观的界面和先进的工具&#xff0c;用户可以快速进行文本编辑、图像调整、页面管理等操作&#xff0c;同时支持OCR技术&#…...

玩一下Spring Boot

文章目录 1 开发环境1.1 JDK1.2 IntelliJ IDEA2 Spring Boot2.1 创建项目2.2 创建模板页面2.3 创建控制器2.4 启动项目2.5 访问页面1 开发环境 1.1 JDK 安装JDK21 配置环境变量 在命令行查看JDK版本 玩一玩jshell...

一个高性能类型安全的.NET枚举实用开源库

从零构建.Net前后端分离项目 枚举应该是我们编程中&#xff0c;必不可少的了&#xff0c;今天推荐一个.NET枚举实用开源库&#xff0c;它提供许多方便的扩展方法&#xff0c;方便开发者使用开发。 01 项目简介 Enums.NET是一个.NET枚举实用程序库&#xff0c;专注于为枚举提…...

c#字符串格式化

字符串格式化是一种将变量的值插入到字符串中的方法。它允许我们创建动态的字符串&#xff0c;其中包含变量的值。 string.Format 通过在字符串中使用占位符{0}&#xff0c;{1}等&#xff0c;我们可以指定要插入的变量的位置。然后&#xff0c;通过在string.Format方法的参数…...

AMD老电脑超频及性能提升方案及实施

收拾电子元件的时候找到了若干古董的CPU 其中有一个X3 440 是原来同学主板烧了之后给我的&#xff0c;我从网上配了AM2 昂达主板&#xff0c;然后又买了AMD兼容内存&#xff0c;组成了win7 64位电脑&#xff0c;用起来非常不错&#xff0c;我把硬件配置和升级过程说明下&#x…...

BaiduPCS-Web:智能突破百度网盘限速的革命性解决方案

BaiduPCS-Web&#xff1a;智能突破百度网盘限速的革命性解决方案 【免费下载链接】baidupcs-web 项目地址: https://gitcode.com/gh_mirrors/ba/baidupcs-web 还在为百度网盘的下载速度而烦恼吗&#xff1f;当急需下载重要文件时&#xff0c;几十KB/s的速度是否让你感到…...

SEO_从零开始,手把手教你制定有效的SEO策略

SEO基础知识&#xff1a;什么是SEO&#xff1f; 在互联网时代&#xff0c;拥有一个高效的SEO策略是任何网站希望获得更多流量和更高知名度的关键。SEO&#xff0c;全称搜索引擎优化&#xff08;Search Engine Optimization&#xff09;&#xff0c;是通过优化网站的内容和结构…...

YOLOv8鹰眼快速入门:三步完成图像上传、检测与结果查看

YOLOv8鹰眼快速入门&#xff1a;三步完成图像上传、检测与结果查看 1. 引言&#xff1a;为什么选择YOLOv8鹰眼目标检测 在计算机视觉领域&#xff0c;目标检测技术正变得越来越重要。无论是安防监控、自动驾驶还是工业质检&#xff0c;快速准确地识别图像中的物体都是核心需求…...

靠专业建议收咨询费!传统旅游顾问转型AI行程规划师,如何在高定市场赚大钱

“上个月&#xff0c;我的咨询费增了好多。”说出这个数字时&#xff0c;前旅行社门店顾问小雅脸上带着自信的笑容。曾经的“人肉攻略机器”到如今的AI高端定制规划师&#xff0c;小雅的转型故事&#xff0c;或许能给所有被困在低价内卷里的旅游从业者带来全新的思路。一、转型…...

避坑指南:用Pixhawk 4飞控连接Nooploop TOFSense激光雷达,这些线序错误千万别犯

Pixhawk 4与TOFSense激光雷达安全接线全攻略&#xff1a;从接口定义到防烧毁实战 当你第一次拿到TOFSense激光雷达模块时&#xff0c;那种迫不及待想把它接入飞控的心情我完全理解——毕竟谁不想让自己的无人机立刻获得精准的测距能力呢&#xff1f;但作为一个曾经因为接错线而…...

深入解析C语言malloc(0)的内存分配机制

1. 深入解析 malloc(0) 的行为机制在 C 语言编程中&#xff0c;内存管理是一个基础但极其重要的话题。malloc 函数作为动态内存分配的核心工具&#xff0c;其行为规范在 C 标准中有明确定义。然而&#xff0c;当我们遇到像 malloc(0) 这样的边界情况时&#xff0c;事情就变得有…...

终极指南:如何从零构建Cubism.js自定义数据源适配器

终极指南&#xff1a;如何从零构建Cubism.js自定义数据源适配器 【免费下载链接】cubism Cubism.js: A JavaScript library for time series visualization. 项目地址: https://gitcode.com/gh_mirrors/cu/cubism Cubism.js是一个强大的JavaScript时间序列可视化库&…...

免费域名会不会对网站SEO造成影响_免费域名对网站性能和访问速度有影响吗

免费域名会不会对网站SEO造成影响 在互联网时代&#xff0c;网站的建设和推广是每个企业和个人都必须面对的挑战。其中&#xff0c;域名作为网站的身份和地址&#xff0c;对于网站的SEO&#xff08;搜索引擎优化&#xff09;有着重要影响。而免费域名的出现&#xff0c;给许多…...

Burp Suite实战:如何用Base64编码爆破网站登录(附完整配置流程)

Burp Suite高级实战&#xff1a;Base64编码爆破攻击的深度解析与防御策略 在渗透测试领域&#xff0c;认证机制的安全性评估始终是核心环节。Base64编码作为一种常见的数据表示方式&#xff0c;常被误认为具有加密功能而用于认证传输。本文将深入剖析如何利用Burp Suite对采用B…...

补题记录2

牛客周赛137 C D Epta 天梯赛6 8,9,10,11...