并查集与图

news2024/9/28 17:36:27

并查集与图

  • 一、并查集
    • 概念
    • 实现原理
    • 代码实现
      • 查找根节点
      • 合并两颗树
      • 判断是否是同一棵树
      • 树的数量
  • 二、图的基本概念
    • 定义
    • 分类
    • 完全图
    • 顶点的度
    • 连通图
  • 三、图的存储结构
    • 分类
    • 邻接表
      • 邻接表的结构
      • 代码实现
    • 邻接矩阵
      • 代码实现
  • 四、图的遍历
    • 方式
    • 广度优先
    • 深度优先
  • 五、最小生成树
    • 概念
    • 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.coloradmin.cn/o/1410594.html

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

相关文章

在linux部署Prometheus+Grafana+Exporter监控系统性能

Prometheus、Grafana和Report组件是什么? Prometheus、Grafana和Exporter是常用于系统监控和指标收集的组合。 Prometheus是一种开源的系统监控和警报工具。它可以收集各种指标数据,并提供强大的查询语言和灵活的警报规则,用于实时监控系统…

ChatGPT+Midjourney+闲鱼赚钱方法实战探索

最近天天在朋友群内看到朋友接单(出售提示词,图片),轻轻松松半小时就赚200-300,特意探索了一下相关玩法,总结出一套ChatGPTMidjourney闲鱼赚钱方法,主打的是易上手,有可操作性! 具体…

03. 静态路由

文章目录 一. 静态路由概述1.1. 概述1.2. 路由信息获取方式1.3. 路由表的参数1.4. 路由协议的优先级1.5. 最优路由条目优先1.6. 最长前缀匹配原则 二. 实验实操2.1. 实验1:静态路由2.1.1. 实验目的2.1.2. 实验拓扑图2.1.3. 实验步骤(1)配置网…

计算机网络的体系结构的各层在整个过程中起到什么作用?

ps:本文章的图片内容来源都是来自于湖科大教书匠的视频,声明:仅供自己复习,里面加上了自己的理解 这里附上视频链接地址:1.6 计算机网络体系结构(4)—专用术语_哔哩哔哩_bilibili 目录 &#x…

uniapp上传音频文件到服务器

视频教程地址: 【uniapp录音上传组件,将录音上传到django服务器】 https://www.bilibili.com/video/BV1wi4y1p7FL/?share_sourcecopy_web&vd_sourcee66c0e33402a09ca7ae1f0ed3d5ecf7c uniapp 录制音频文件上传到django服务器保存到服务器 &#xf…

binary_search_tree的介绍与实现(二叉搜索树精美图示详解哦)

二叉搜搜索树 引言二叉搜索树的介绍二叉搜索树的实现框架默认成员函数构造析构赋值重载 InsertR(插入)EraseR(删除)SearchR(查找) 源码概览总结 引言 在C语言部分,我们已经认识了树与二叉树的结…

docker的资源限制(cgroup)

前瞻 Docker 通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面, 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写,是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、…

Linux文件管理技术实践

shell shell的种类(了解) shell是用于和Linux内核进行交互的一个程序,他的功能和window系统下的cmd是一样的。而且shell的种类也有很多常见的有c shell、bash shell、Korn shell等等。而本文就是使用Linux最常见的bash shell对Linux常见指令展开探讨。 内置shell…

【大模型研究】(1):从零开始部署书生·浦语2-20B大模型,使用fastchat和webui部署测试,autodl申请2张显卡,占用显存40G可以运行

1,演示视频 https://www.bilibili.com/video/BV1pT4y1h7Af/ 【大模型研究】(1):从零开始部署书生浦语2-20B大模型,使用fastchat和webui部署测试,autodl申请2张显卡,占用显存40G可以运行 2&…

重磅!证监会回应股市波动!2万亿元救市计划正在商榷!将提振比特币?

最近这段时间,国内资本市场震荡走弱、波动加大,一些投资者深感忧虑。多家机构表示,市场波动已引起高层的重视。 继1月23日,证监会党委扩大会议从宏观层面提出资本市场建设发力重点后,1月24日证监会副主席王建军的一席采…

工作软技能第一弹,关于职场沟通、成长的那些事

引言 在谈绩效后,我收获了一些心得,在此梳理出来,加深印象并且共勉 基本信息 在步入职场后,你可能跟我一样虽然技术水平有在上升,但是在处理一些事情上可能偶尔没能获得预期的成果。我在通过绩效沟通以及自我反思后…

centos系统安装Ward服务器监控工具

简介 Ward是一个简约美观多系统支持的服务器监控面板 安装 1.首先安装jdk yum install java-1.8.0-openjdk-devel.x86_64 2.下载jar wget 3.启动 java -jar ward-1.8.8.jar 体验 浏览器输入 http://192.168.168.110:4000/ 设置服务名设置为:myserver 端口号:5000 点击…

php实现多进程的几种方式

目录 一:使用pcntl扩展库 二:使用Swoole扩展 三:使用多进程模式PHP-FPM 在PHP中实现多进程主要有以下几种方式: 一:使用pcntl扩展库 pcntl扩展库提供了多线程相关的函数,如pcntl_fork()用于创建子进程…

探索设计模式的魅力:深入理解面向对象设计的深层原则与思维

如何同时提高一个软件系统的可维护性 和 可复用性是面向对象对象要解决的核心问题。 通过学习和应用设计模式,可以更加深入地理解面向对象的设计理念,从而帮助设计师改善自己的系统设计。但是,设计模式并不能够提供具有普遍性的设计指导原则。…

C#用DateAndTime.DateDiff方法和TimeSpan分别计算时间间隔

目录 一、计算时间间隔的方法 1.用DateAndTime.DateDiff方法计算时间间隔 2.使用TimeSpan获取日期时间间隔 二、实例 1.示例一:用DateAndTime.DateDiff方法计算时间间隔 2.示例二:使用TimeSpan获取日期时间间隔 一、计算时间间隔的方法 1.用Date…

vue3 组件通信 mitt

mitt 安装 pnpm add mitttypescript 在 tsconfig.json 中设置 “strict”: true {"compilerOptions": {"strict": true,} }使用 导出 emitter src/utils/mitt/index.ts import mitt from mitttype Events {get-name: string }export const emitter …

go-zero 统一返回

1、整体目录结构 1、全局处理主入口 package manageimport ("net/http""github.com/zeromicro/go-zero/rest/httpx" )type Body struct {Code int json:"code"Message string json:"message"Result interface{} jso…

每日一道Java面试题:方法重载与方法重写,这把指定让你明明白白!

写在开头 请聊一聊Java中方法的重写和重载? 这个问题应该是各大厂面试时问的最多的话题之一了,它们几乎贯穿了我们日常的开发工作,在过往的博客中我们多多少少都提到过重载与重写,而今天我们就一起来详细的学习一下这二者的功能与…

arcgis实现截图/截屏功能

arcgis实现截图/截屏功能 文章目录 arcgis实现截图/截屏功能前言效果展示相关代码 前言 本篇将使用arcgis实现截图/截屏功能&#xff0c;类似于qq截图 效果展示 相关代码 <!DOCTYPE html> <html> <head><meta charset"utf-8"><meta nam…

InnoDB索引

B树与B树 索引的数据结构就是B树&#xff0c;它的叶子节点存储数据(数据页)&#xff0c;非叶子节点存储索引(索引页)。 所以索引走树&#xff0c;全表扫走叶子节点的单向链表(mysql里优化成双向) 二级索引页(非主键) 多个目录项记录 目录项记录 每页记录的最小值 主键值 …