并查集与图

并查集与图

  • 一、并查集
    • 概念
    • 实现原理
    • 代码实现
      • 查找根节点
      • 合并两颗树
      • 判断是否是同一棵树
      • 树的数量
  • 二、图的基本概念
    • 定义
    • 分类
    • 完全图
    • 顶点的度
    • 连通图
  • 三、图的存储结构
    • 分类
    • 邻接表
      • 邻接表的结构
      • 代码实现
    • 邻接矩阵
      • 代码实现
  • 四、图的遍历
    • 方式
    • 广度优先
    • 深度优先
  • 五、最小生成树
    • 概念
    • Kruskal算法
      • 原理
      • 代码实现
    • Prim算法
      • 原理
      • 代码实现
  • 六、单源最短路径
    • 概念
    • Dijkstra
      • 原理
      • 代码实现
      • 缺陷
    • BellmanFord
      • 原理
      • 代码实现
  • 七、多源最短路径
    • 概念
    • 原理
    • 代码实现

一、并查集

概念

并查集是由多棵树组成的,本质上一个森林,常用于解决图的判环问题,两个集合是否有交集等等。

实现原理

并查集采用双亲表示法,和堆类似,都采用数组来实现,如下图,以10个元素为例,初始时,值都是-1,表示10棵树,元素值的绝对值表示树中的节点个数
在这里插入图片描述
如下图,将下标为9的元素合并到下标为5的树上,将下标为5的值加上下标为9的值,然后将下标为9的值改为5,便于找到它的双亲
在这里插入图片描述

代码实现

查找根节点

要合并两个树,就得先分别找到这两颗树的根节点,然后才能进行合并,如下图
在这里插入图片描述

合并两颗树

首先先找到两颗树的根节点,根据根节点是否相同,来判断是不是已经是同一颗树了,如果是就返回,不是再进行合并,同时,将节点少的树往节点多的树上合并
在这里插入图片描述

判断是否是同一棵树

只要判断是不是同一个根节点即可
在这里插入图片描述

树的数量

只要元素的值为-1的,就表示它是一棵树,统计计数即可
在这里插入图片描述

二、图的基本概念

定义

图是由顶点和边组成的一种数据结构,用G = (V, E)表示,G表示图(graph),V(vertex)表示顶点,E(edge)表示边

分类

图分为有向图和无向图两种,有向图常用于表示单向关系,比如B站关注了某个up主,就是单向的,而无向图常用于表示像微信、QQ这样双向的好友关系

有向图,如下图
在这里插入图片描述

无向图,如下图
在这里插入图片描述

完全图

完全图是一种任意两个顶点都直接相连的图,无向图中的完全图有n*(n-1)/2条边,有向图中的完全图有n*(n-1)条边,即任意两个顶点都有两条边

顶点的度

无向图中,顶点的度=出度=入度,因为无向图的边没有方向,所以都相等,而在有向图中,顶点的度=出度+入度

连通图

图和树不同,图不一定是连通的,可能存在孤岛,即没有前往某个节点的路径,它与其它节点是脱离开的,如下图,红色顶点就是一个孤岛
在这里插入图片描述

三、图的存储结构

分类

图的存储结构分为两种,一种是邻接矩阵

邻接表

邻接表的结构

邻接表采用类似于哈希表的方式,先用一个数组,数组的每个元素都代表一个顶点,顶点下面都挂着的一个链表,链表的每个节点都是一条边,对于有向图,这里这考虑出边,不考虑入边,如果要考虑入边,就得再加一个邻接表
在这里插入图片描述

代码实现

首先,定义出边的结构,用模板类型W,来表示权值类型,因为是挂在对应的顶点下面,所以可以不存储顶点的下标
在这里插入图片描述
顶点的类型可能有很多中,所以采用模板类型V,W是权值的类型,Direction是非类型模板参数,false表示无向图,true表示有向图
在这里插入图片描述
确定图的成员,分别有顶点集合,邻接表,以及一个顶点与其下标映射的Map,便于后面插入的时候,找到顶点的下标
在这里插入图片描述
构造函数用来开辟邻接表的空间,以及初始化成员
在这里插入图片描述
定义一个查找顶点下标的接口
在这里插入图片描述
添加边,采用链表的头插,如果是无向图,则需要插入两条边,因为i->j,那也一定可以j->i,所以需要插入两条边
在这里插入图片描述

邻接矩阵

代码实现

MAX_W这个参数用来初始化二维数组,毕竟一开始的邻接矩阵的每个顶点都是一个孤岛
在这里插入图片描述
成员和邻接表类似,只是将邻接表改为了二维数组,二维数组的每个元素的值,都是边的权值
在这里插入图片描述
构造函数,用来开辟空间,初始化成员
在这里插入图片描述
添加边,这里采用两个函数,是因为后面有些地方会直接使用上面的函数,不需要通过函数获取顶点下标
在这里插入图片描述
注意:下面的所有算法,都是在邻接矩阵中实现的

四、图的遍历

方式

如图、树这种数据结构,一般都采用深度优先或广度优先的方式来进行遍历,值得注意的是,这里遍历的是顶点,不是边!!!

广度优先

广度优先遍历方式,需要借助队列来实现,队列用来存顶点的下标,srci是起始顶点的下标,visited是一个标记数组,当某个顶点下标入队列后,就将其标记为true,表示访问过了,来防止后续可能会重复入队列,第一个for循环是用来便于一层一层打印的,类似于打印树的每一层
在这里插入图片描述
值得注意的是,图不一定是连通的,可能存在孤岛,遍历不到,所以需要循环遍历标记数组,以此来遍历所有顶点
在这里插入图片描述

深度优先

深度优先遍历,采用递归的方式实现,同样需要借助标记数组,来标记访问过的节点
在这里插入图片描述
同广度优先,需要解决可能出现的孤岛问题
在这里插入图片描述

五、最小生成树

概念

最小生成树是一种特殊的连通图,它只有n-1条边,刚刚好可以使图连通,n是顶点个数,最小生成树也是不能成环的,否则也无法使图连通,同时,这n-1条边的权值和是最小的。

注意:最小生成树也可能不唯一!!!

Kruskal算法

原理

Kruskal算法是一种找全局最优解的贪心,它每次都找最权值最小的边,当然,在会构成环的时候,会抛弃构成环的那条边,找另外的边

代码实现

首先,先初始化一下最小生成树
在这里插入图片描述
在这里插入图片描述
这是要使用的边结构,重载>,是为了后面建立小堆
在这里插入图片描述

这里借助优先级队列,来便于每次找最小的边
在这里插入图片描述
选边,需要借助前面讲过的并查集,来判断是不是会成环,成环则抛弃这条边,找另外的边,不成环,将边的起始点和终止点的下标加入并查集,来合并顶点
在这里插入图片描述
最后,再判断一下,是否是n-1条边,是就将权值和返回
在这里插入图片描述

Prim算法

原理

Prim算法是一种找局部最优解的贪心,它采用了两个集合,集合中的元素是顶点的下标,姑且称为源集合和目标集合,分别用X和Y表示。开始时,X只有一个顶点a的下标,Y有其它顶点的下标,然后找顶点a到Y集合中元素对应的顶点的最小权值,具体步骤如下图

核心思路:每次找X中的某个顶点到Y中的某个顶点直接相连的且是最小权值的边
在这里插入图片描述

代码实现

初始准备工作
在这里插入图片描述
定义X与Y集合,开始时,X集合只有一个元素,Y集合有n-1个元素
在这里插入图片描述
先把a顶点直接相连的边全部插入到优先级队列中,此后,优先级队列中都是X集合中的顶点连接的边
在这里插入图片描述
选出优先级队列中的最小边,判断边的目标顶点是不是已经在X集合中了,在就表示成环了,因为一个顶点不可能被两次加入一个集合

添加边后,再将边的目标点连接的边都加入到优先级队列中,不过需要判断一下目标点连接的边的另一顶点是否已经在X集合中了
在这里插入图片描述
最后,判断一下是否是n-1条边
在这里插入图片描述

六、单源最短路径

概念

单源最短路径,指的是从某个点到其它点的路径,假设有顶点a、b、c、d、e,以a为源点,从a到b所有路径中,权值和最小的那条路径就是最短路径,而a到c、d、e,也是同理,所以被称为单源最短路径

Dijkstra

原理

这里采用两个一维数组,长度为顶点的个数,一个数组中的每个元素表示源点到该元素顶点的路径的权值的最小值,另一个数组中的每个元素存储的是它的双亲,具体情况,如下图,*表示最大值,以S为源点,先根据S的所有出边,更新对应的最短路径,s到y和t的最短路径被更新,然后以y为起点,找它的出边,更新s到t、x、z的最短路径,因为s到z的路径最短,下次再以z为起点,找它的出边等等,每一步都是贪心

在这里插入图片描述

代码实现

先进行初始化操作,数组S用来标记已经找到最短路径的顶点
在这里插入图片描述
因为有n个顶点,所以最外层循环n次,第一个内循环,则是找出路径权值最小的起点,第二个内循环则负责更新出最短路径,同时要保证目标顶点没有被确定最短路径
在这里插入图片描述

缺陷

Dijkstra算法的效率很高,但是也存在缺陷,就是无法解决带有负权路径的情况,因为此时使用贪心就不准确了,不能每次确定最短路径顶点

BellmanFord

原理

BellmanFord算法采用了暴力思想,通过把一条路径都遍历一遍,来确定源点到其它点的最短路径,虽然效率不如Dijkstra算法,但可以很好地解决负权路径问题

代码实现

初始化工作
在这里插入图片描述
内部的两层循环,把每一条路径都遍历一遍,来找到源点到其它点的最短路径,但可能一轮循环无法更新所有源点到其它顶点的最短路径,所以还需要在最外面套一层循环,循环n-1次,来更新出源点到其它点的所有最短路径,至于为什么是n-1,是因为在一条路径上,你只需要n-1条边来连接n个节点,再多的边就构成了一个环路,这里定义了一个变量,当没有更新的时候,也就说明所有源点到其它顶点的最短路径都已经被找到了
在这里插入图片描述
循环完后,还需要判断一下是否存在负权回路,毕竟存在负权回路时,是不可能有最短的路径的
在这里插入图片描述

七、多源最短路径

概念

多源最短路径,则是求的任意两个顶点的最短路径

原理

采用的是FloydWarshall算法,核心思想是动态规划,来寻找最优解,比如找i->j的最短路径,则可以找i->k,k->j的和的最短路径,k为i->j路径上的一个中间点,也有可能k就是i

代码实现

初始化操作,这里采用两个矩阵的形式,同上面的两个算法,只不过变为了二维,同时将直接相连的边在矩阵中进行初始化
在这里插入图片描述
result[i][j],表示从i对应的顶点到j对应的顶点的最短路径值,pPath[i][j],表示i对应顶点到j对应顶点的最短路径中,j对应顶点的父顶点
在这里插入图片描述

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

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

相关文章

网络原理-初识(2)

协议分层 对于网络协议来说,往往分成几个层次进行定义. 网络通信的过程中,需要涉及到的细节,其实非常多.如果要有一个协议来完成网络通信,就需要约定好方方面面的内容,导致非常复杂. 而如果拆分的话,就十分复杂,庞大,因此需要分层. 什么是协议分层 即只有相邻的层次可以沟通,…

代码随想录 Leetcode102. 二叉树的层序遍历

题目&#xff1a; 代码(首刷看解析 2024年1月24日&#xff09;&#xff1a; class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res;if(root nullptr) return res;queue<TreeNode*> que;TreeNode…

蓝桥杯备战——5.动态数码管扫描

1.分析原理图 经查阅说明书得知数码管为共阳极&#xff0c;共阳端口接到了U8,而段码接到了U7。 如果需要选中U8,我们只需要将P250;P261;P271; 如果需要选中U7,我们只需要将P251;P261;P271; 2.代码示例 void Delay1ms() //12.000MHz {unsigned char data i, j;i 12;j 169;…

【2024】新建mysql数据库,如何选择字符集和排序规则

如何使用 Navicat 新建 MySQL 数据库&#xff0c;并选择字符集与排序规则 如何使用 Navicat 新建 MySQL 数据库并选择字符集与排序规则1. 开始之前2. 新建数据库步骤 1: 打开 Navicat步骤 2: 创建新数据库步骤 3: 填写数据库名称 常见的字符集和排序规则及其选择场景1. 字符集&…

7.前端--CSS-复合选择器

1.什么是复合选择器 复合选择器是由两个或多个基础选择器&#xff0c;通过不同的方式组合而成的&#xff0c;可以更准确、更高效的选择目标元素&#xff08;标签&#xff09; 常用的复合选择器包括&#xff1a;后代选择器、子选择器、并集选择器、伪类选择器等等 2.后代选择器 …

flink基础概念之什么是时间语义

什么是时间语义 Flink支持三种不同的时间语义&#xff0c;以便处理流式数据中的事件时间、处理时间和摄入时间。 1. 处理时间&#xff08;Processing Time&#xff09; 处理时间的概念非常简单&#xff0c;就是指执行处理操作的机器的系统时间。 在这种时间语义下处理窗口非…

接口自动化测试实践

众所周知&#xff0c;接口自动化测试有着如下特点&#xff1a; 低投入&#xff0c;高产出。 比较容易实现自动化。 和UI自动化测试相比更加稳定。 如何做好一个接口自动化测试项目呢&#xff1f; 我认为&#xff0c;一个“好的”自动化测试项目&#xff0c;需要从“时间”…

05-Seata下SQL使用限制

不支持 SQL 嵌套不支持多表复杂 SQL(自1.6.0版本&#xff0c;MySQL支持UPDATE JOIN语句&#xff0c;详情请看不支持存储过程、触发器部分数据库不支持批量更新&#xff0c;在使用 MySQL、Mariadb、PostgreSQL9.6作为数据库时支持批量&#xff0c;批量更新方式如下以 Java 为例 …

掌握大语言模型技术: 推理优化

掌握大语言模型技术_推理优化 堆叠 Transformer 层来创建大型模型可以带来更好的准确性、少样本学习能力&#xff0c;甚至在各种语言任务上具有接近人类的涌现能力。 这些基础模型的训练成本很高&#xff0c;并且在推理过程中可能会占用大量内存和计算资源&#xff08;经常性成…

C++:反向迭代器-reverse_iterator

目录 1.关于反向迭代器 2.反向迭代器的成员函数 1.构造 2.base 3.operator* 4.operator 5.operator-- 6.operator-> 7.operator[] 3.反向迭代器的模拟实现 小结 1.关于反向迭代器 在C中&#xff0c;可以使用反向迭代器来逆序遍历容器中的元素。反向迭代器是通过…

链表的中间结点,简单的快慢指针问题

总结 struct ListNode* middleNode(struct ListNode* head) {struct ListNode*fasthead;struct ListNode*slowhead;while( fast && fast->next)//结束条件{slowslow->next;fastfast->next->next;}return slow; }

组件冲突、data函数、组件通信

文章目录 1.组件的三大组成部分 - 注意点说明2.组件的样式冲突&#xff08;用 scoped 解决&#xff09;3.data是一个函数4.组件通信1.什么是组件通信&#xff1f;2.不同的组件关系 和 组件通信方案分类 5.prop详解prop 校验①类型校验②完整写法&#xff08;类型&#xff0c;非…

REVIT二次开发设置门垛高度

步骤1 步骤2 步骤3 using System; using System.Collections.Generic; using System.Linq; using System

Redis 持久化详解:RDB 与 AOF 的配置、触发机制和实际测试

什么是持久化&#xff1f; 就是 Redis 将内存数据持久化到硬盘&#xff0c;避免从数据库恢复数据。之所以避免从数据库恢复数据是因为后端数据通常有性能瓶颈&#xff0c;大量数据从数据库恢复可能会给数据库造成巨大压力。 Redis 持久化通常有 RDB 和 AOF 两种方式&#xff…

计算机网络 第5章(运输层)

系列文章目录 计算机网络 第1章&#xff08;概述&#xff09; 计算机网络 第2章&#xff08;物理层&#xff09; 计算机网络 第3章&#xff08;数据链路层&#xff09; 计算机网络 第4章&#xff08;网络层&#xff09; 计算机网络 第5章&#xff08;运输层&#xff09; 计算机…

vue3之 websoket发送消息

1.封装websoket var ws null; //建立的连接 var lockReconnect false;//是否真正建立连接 var timeout 6 * 1000 * 5;//30秒一次心跳 var timeoutObj null;//心跳心跳倒计时 var serverTimeoutObj null;//心跳倒计时 var timeoutnum null;//断开 重连倒计时 var global_…

DA14531平台secondary_bootloade工程修改笔记

DA14531平台secondary_bootloade工程修改笔记 1.支持在线仿真 初始时加入syscntl_load_debugger_cfg(); 表示可以重复Jlink连接调试仿真 2.支持串口烧录&#xff0c;和支持单线线写 utilities\secondary_bootloader\includes\bootloader.h /************** 2-wire UART supp…

Siamese network 孪生神经网络--一个简单神奇的结构

1.名字的由来 Siamese和Chinese有点像。Siam是古时候泰国的称呼&#xff0c;中文译作暹罗。Siamese也就是“暹罗”人或“泰国”人。Siamese在英语中是“孪生”、“连体”的意思&#xff0c;这是为什么呢&#xff1f; 十九世纪泰国出生了一对连体婴儿&#xff0c;当时的医学技术…

点赞!HashData连续三年获评数据猿“最具投资价值企业奖”

近日&#xff0c;由上海市经济和信息化委员会、上海市科学技术委员会指导&#xff0c;数据猿和上海大数据联盟共同主办的“第六届金猿季&魔方论坛——大数据产业发展论坛”在上海举行。本次活动以“小趋势大未来”为主题&#xff0c;展示了大数据与人工智能、云计算、5G等新…

仰暮计划|“她已跨过了八旬的门槛,一个人见证了时光洪流的智慧年代”

倾听与关爱 2023年7月4日中午&#xff0c;我跟随“羽翼”社会实践服务队、党员服务小组一起到柏桥村完成我们本次三下乡的调研任务&#xff0c;通过走访当地居民并与当地党群服务中心干部进行交谈了解当地乡村振兴落实情况。 在走往柏桥村的路上&#xff0c;我有幸遇到了教师…