【高阶数据结构(一)】并查集详解

💓博主CSDN主页:杭电码农-NEO💓

⏩专栏分类:高阶数据结构专栏⏪

🚚代码仓库:NEO的学习日记🚚

🌹关注我🫵带你学习更多Go语言知识
  🔝🔝


在这里插入图片描述

高阶数据结构

  • 1. 前言
  • 2. 并查集的原理
  • 3. 并查集的实现
  • 4. 并查集的应用
  • 5. 总结以及拓展

1. 前言

本系列会带大家走进高阶数据结构的学习, 其中包括并查集,图论, LRU cache, B树, B+树, B*树, 跳表. 其中, 图论中讲解的时间最长, 包括邻接表, 邻接矩阵, 广度优先遍历, 深度优先遍历, 最小生成树, 以及prim算法, dijkstra算法, bellman-Ford算法, Floyd-wars hall算法. 高阶数据结构属于拓展内容, 建议把基础掌握好后再学

本章重点:

本篇文章着重讲解并查集的原理, 并查集的实现(CPP),以及并查集的应用


2. 并查集的原理

在一些应用问题中,需要将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union-find set)。

比如, 公司招的10个人当中有4人是北京的,三人是上海的,3人是深圳的. 那么他们就可以被分为三个不同的集合. 现在将他们进行编号(0~9),然后来看看如何将他们进行分组(为什么初始值为-1,后面再解释)

在这里插入图片描述

北京学生: 0,6,7,8.上海学生: 1,4,9.深圳学生: 2,3,5
假如选出0,1,2号学生作为小组的组长

在这里插入图片描述

现在需要在数组中,表示三个分组, 不卖关子,直接讲解并查集的原理. 当组长的人的位置的值是负数,-n代表这个组有n个人. 而非组长的成员的位置的值存储的是组长的下标,这样说可能有点抽象,下面来画个图看看

在这里插入图片描述

北京小组的组长是0,它的值是-4代表此小组有四个人.6,7,8是0的组员,所以它们存储的值是0,也就是组长的下标. 所以刚开始初始值为-1,代表每一个数都自成一个集合

现在出现一个情况, 由于北京的同学和上海的同学经常在一起玩耍, 所以久而久之他们就很熟了,就想着将这两个分组合并.于是出现了以下的情况:

在这里插入图片描述

此时,下标为1的位置应该存储它的父亲,也就是0,下标为4.9的位置不能直接存储0,而是应该存储1,因为1才是他们的直系父亲. 可以用下图来表示:

在这里插入图片描述

你可以窥探到,下标为0的值从-4变为-7,而下标为1的值从-3变为0,实际上就为我们后面的手撕并查集提供了思路


3. 并查集的实现

在进行并查集实现时,应该要拥有这几个基础功能函数: 找到一个下标的根, 合并两个集合, 判断两个树是否在同一个集合. 计算此并查集一共有几个集合.

并查集的本质是数组,所以可以这样定义结构:

class UnionFindSet
{
public:UnionFindSet(size_t n):_ufs(n,-1)//初始化数组,初始值设为-1
private:vector<int> _ufs;	
};

首先可以先实现,找到一个下标的根,后续的函数可以复用它:

int FindRoot(int x)//找到一个下标的根
{int parent = x;while (_ufs[parent] >= 0)parent = _ufs[parent];//路径压缩.下次查找时效率就高了(压缩当前节点以及它的父亲节点)while (_ufs[x] >= 0){int tmp = _ufs[x];_ufs[x] = parent;x = tmp;}return parent;
}

这份代码可以分为两步,第一步就是在找它的根,就是一直向前找直到遇见负数.第二部分的代码在进行路径压缩工作,若是有多个集合进行合并,那么我们的树可能就会很高,查找最下面的树的根时,就会出现效率低下的问题,所以进行路径压缩很有必要. 关于路径压缩的原理如下:

在这里插入图片描述
下次再查找4的时候,就优化了时间

接下来的代码就简单了:

#pragma once
#include<vector>
#include<iostream>
using namespace std;
class UnionFindSet
{
public:UnionFindSet(size_t n):_ufs(n,-1){}void Union(int x1, int x2) //合并两个集合{int root1 = FindRoot(x1);int root2 = FindRoot(x2);if (root1 == root2) return;if (_ufs[root1] < _ufs[root2]){_ufs[root1] += _ufs[root2];_ufs[root2] = root1;}else{_ufs[root2] += _ufs[root1];_ufs[root1] = root2;}}int FindRoot(int x)//找到一个下标的根{int parent = x;while (_ufs[parent] >= 0)parent = _ufs[parent];//路径压缩.下次查找时效率就高了(压缩当前节点以及它的父亲节点while (_ufs[x] >= 0){int tmp = _ufs[x];_ufs[x] = parent;x = tmp;}return parent;}bool SameSet(int x1, int x2)//判断这两个数是否在同一个集合{return FindRoot(x1) == FindRoot(x2);}size_t SetSize()//这个并查集一共有几个集合{size_t size = 0;for (auto x : _ufs)if (x < 0)size++;return size;}
private:vector<int> _ufs;	
};

判断两个数是否在同一集合,以及一共有几个集合,这两个函数比较简单,不做讲解. 合并两个集合先要找到这两个数的根,如果这两个数有相同的根就直接返回,否则就开始合并.合并的逻辑也非常简单,其中的if,else语句不是必须的


4. 并查集的应用

由于我是学生,所以我先给大家看看并查集在校招中考察的多不多,这道题: 省份数量是19年美团笔试的原题,并且今年24年的笔试疑似也出现过并查集解题. 除此之外, 华为考察算法和数据结构也比较厉害.其中的考点之一就有并查集:

在这里插入图片描述

并查集往往用于解决图上的问题,并查集只有两个操作,“并” 和 “查”,但是通过这两个操作可以派生出一些其他的应用:

  • 图的连通性问题
  • 集合的个数
  • 集合中元素的个数

并且在后面学习图论的过程中,也会涉及到并查集的知识,会复用并查集的代码. 这也是我优先讲并查集的原因之一, 如果你没有学过并查集直接去搞图论,可能会十分吃力


5. 总结以及拓展

并查集只是高阶数据结构中的开胃菜,后面的数据结构会越来越难,请大家耐心学习


🔎 下期预告:图论 🔍

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

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

相关文章

等保2.0有哪些好处,到底要花多少钱?今天一个文章给你讲透

自从等保2.0相关标准正式发布以来&#xff0c;等级保护测评已然成为网络安全行业的热门话题&#xff0c;这意味着等保进入了一个全新的高度。 目前一些机构国家单位项目都有等保资质这一项&#xff0c;早做的客户符合这一标准&#xff0c;竞争项目就更有把握了。 第一次做完等…

数据分析的统计推断

数据分析的统计推断 前言一、提出问题二、统计归纳方法三、统计推断四、统计推断步骤如何进行统计推断统计推断的基本问题点估计区间估计总体方差已知总体方差未知 假设检验假设检验的假设显著性水平 五、检验统计量常见的检验统计量 六、检验方法七、拒绝域八、假设检验步骤九…

【JavaEE网络】从数据链路层到应用层的DNS

目录 数据链路层以太网 DNS 数据链路层 越往下与程序员越远 代表协议&#xff1a;以太网。平常用的网线也叫“以太网线”&#xff0c;平常用的交换机也叫“以太网交换机” 以太网 认识以太网 “以太网” 不是一种具体的网络&#xff0c;而是一种技术标准&#xff1b;既包含…

Day19 代码随想录打卡|字符串篇---反转字符串II

题目&#xff08;leecode T541&#xff09;&#xff1a; 给定一个字符串 s 和一个整数 k&#xff0c;从字符串开头算起&#xff0c;每计数至 2k 个字符&#xff0c;就反转这 2k 字符中的前 k 个字符。 如果剩余字符少于 k 个&#xff0c;则将剩余字符全部反转。如果剩余字符小…

基于uniapp+vue3+vite实现小程序构建Android、iOS多端项目配置详解

&#x1f680; 作者 &#xff1a;“二当家-小D” &#x1f680; 博主简介&#xff1a;⭐前荔枝FM架构师、阿里资深工程师||曾任职于阿里巴巴担任多个项目负责人&#xff0c;8年开发架构经验&#xff0c;精通java,擅长分布式高并发架构,自动化压力测试&#xff0c;微服务容器化k…

网络驱动--汽车ETNB(瑞萨)

以太网AVB (ETNB) 介绍RH850/U2A-EVA的属性&#xff0c;如编号 单元、寄存器的基址。描述了函数和寄存器 ETNB的成员。 两个单元&#xff1b;Units ▪ Fast Ethernet ETNB0 ▪ Gigabit Ethernet ETNB1 单元通道特点 For ETNB0 (Fast Ethernet) ▪ Communication interface ▪…

基于 llama2 的提示词工程案例2

优化大型语言模型&#xff08;LLMs&#xff09; 优化大型语言模型&#xff08;LLMs&#xff09;中的提示词&#xff08;prompts&#xff09;是提高模型性能和输出相关性的重要手段。以下是一些优化提示词的方向&#xff1a; 明确性&#xff1a;确保提示词清晰明确&#xff0c;…

Rust 实战thiserror+自定义错误消息体

导航 一、背景二、实践1、导入thiserror2、自定义错误消息体&#xff08;1&#xff09;创建ErrMsg.rs和创建自定义结构体&#xff08;2&#xff09;lib.rs添加ErrMsg&#xff08;3&#xff09;main函数&#xff08;4&#xff09;完整代码 一、背景 开发中遇到需要通用、能够满…

LeetCode 142.环形链表Ⅱ

题目描述 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内…

速卖通自养号测评技术策略与实战指南

速卖通自养号测评是一个涉及多个步骤和细节的过程&#xff0c;以下是一些关键步骤和注意事项&#xff1a; 1. 准备资源和环境&#xff1a; 测评养号系统&#xff1a;确保账号的权重稳定运营与账号便捷的管理。 海外纯净IP资源&#xff1a;为账号提供稳定的网络环境&#x…

AI新突破:多标签预测技术助力语言模型提速3倍

DeepVisionary 每日深度学习前沿科技推送&顶会论文分享&#xff0c;与你一起了解前沿深度学习信息&#xff01; 引言&#xff1a;多标签预测的新视角 在人工智能领域&#xff0c;尤其是在自然语言处理&#xff08;NLP&#xff09;中&#xff0c;预测模型的训练方法一直在…

地下管线管网三维参数化建模软件MagicPipe3D V3.5

经纬管网建模系统MagicPipe3D&#xff08;www.magic3d.net&#xff09;自主安全可控&#xff0c;本地离线参数化构建三维管网模型&#xff08;管道、接头、附属物等&#xff09;&#xff0c;输出标准3DTiles、Obj等格式&#xff0c;支持Cesium、Unreal、Unity等引擎可视化查询分…

【mysql】深入探索mysql中的各种约束条件

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Java | Spring框架 | Bean的装配之XML配置

Spring | Bean的装配 之XML配置 在Spring框架中&#xff0c;Bean的装配是指将Bean定义和配置信息加载到Spring容器中&#xff0c;以便容器能够管理这些Bean。 Spring支持多种装配方式&#xff0c;其中XML配置是传统但依然有效的方式。 一、 使用XML配置文件定义Bean XML配置…

知识图谱和大语言模型的共存之道

导读 知识图谱和大型语言模型都是用来表示和处理知识的手段。大模型补足了理解语言的能力&#xff0c;知识图谱则丰富了表示知识的方式&#xff0c;两者的深度结合必将为人工智能提供更为全面、可靠、可控的知识处理方法。在这一背景下&#xff0c;OpenKG组织新KG视点系列文章—…

还有谁……想知道“线下与线上布局之间的本质区别”

还有谁……想知道 线下与线上布局之间的本质区别 hello,亲爱的你们好.… 我是你们的好朋友,正博,今天是非常特殊的一天,给每一位读者准备了一份特殊的神秘礼物…… 在分享【特殊礼物】之前,请允许我分享一下《线下营销与线上销售的9大核心差异》…… 1、注意力; 2、销…

浪漫编码:手把手教你实现校园表白墙功能

&#x1f493; 博客主页&#xff1a;从零开始的-CodeNinja之路 ⏩ 收录文章&#xff1a;浪漫编码&#xff1a;手把手教你实现校园表白墙功能 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 这里写目录标题 表白墙数据准备引入MyBatis和MySQL驱动依赖…

华为OD机试【路灯照明问题】(java)(100分)

1、题目描述 在一条笔直的公路上安装了N个路灯&#xff0c;从位置0开始安装&#xff0c;路灯之间间距固定为100米。 每个路灯都有自己的照明半径&#xff0c;请计算第一个路灯和最后一个路灯之间&#xff0c;无法照明的区间的长度和。 2、输入描述 第一行为一个数N&#xff…

中霖教育:哪些地区的一级造价师考试不查社保?

关于一级造价师考试是否查社保的问题&#xff0c;不同地区的规定不一样&#xff0c;部分地区要求社保缴纳时间为1年&#xff0c;部分地区要求6个月&#xff0c;具体还要以资格审核为准。 不用查社保的省份&#xff1a; 江苏、浙江、广东、海南、吉林、黑龙江、内蒙古、山西、…