十、数据结构(图的基础)

news2025/1/21 18:42:18

文章目录

  • 什么是图
      • 图的分类
      • 图算法的复杂度
  • 图的模拟

什么是图

图是常见的抽象模型,由点和连接点的边(edge)组成。图是点和边构成的网。图描述了事物之间的连接。图最典型的应用场景是地图,地图由地点和道路组成,它的特征如下。

  1. 地点:可能是十字路口,也可能是三岔路口,或者仅仅是一个连接点。在图论中,把地点抽象为点。
  2. 道路:可能是单行道或双行道。抽象成有向边或无向边。
  3. 道路有过路费:抽象成边的权值。
  4. 求两点间的最短道路,即图论里的最短路径算法。
  5. 在城市群之间如何修最短的连通道路,即图论中的最小生成树问题。地图的这些问题都是图论研究的对象。计算机网络也是典型的图问题,和地图非常相似。
    树是一种特殊的图。树的结点从根开始,层层扩展子树,是一种层次关系,这种层次关系保证了树上的结点不会出现环路。在图的算法中,经常需要在图上生成一棵树,再进行操作。

图的分类

根据边有无方向、有无权值、有无环路,可以把图分成很多种,例如:

  1. 无向无权图:边没有权值、没有方向;
  2. 有向无权图:边有方向、无权值;
  3. 加权无向图:边有权值,但没有方向;
  4. 加权有向图:边有权值,也有方向
  5. 有向无环图 ( D A G ) (DAG) (DAG)

图算法的复杂度

图算法的复杂度显然和边的数量 E E E、点的数量 V V V相关。如果一个算法的复杂度是线性时间 O ( V + E ) O(V+E) O(V+E),这几乎是图问题中能达到的最好程度了。如果能达到 O ( V l o g 2 E ) O_{(Vlog₂E)} O(Vlog2E) O ( E l o g 2 V ) O(Elog₂V) O(Elog2V)或类似的复杂度,则是很好的算法。如果是 O ( V 2 ) O(V²) O(V2) O ( E 2 ) O(E²) O(E2)或更高,在图问题中不算是好的算法。

图的模拟

怎么储存一个图

对图的任何操作都需要基于一个存储好的图。图的存储结构必须是一种有序的存储,能让程序很快定位结点 u u u v v v 的边 ( u , v ) (u,v) (u,v),最好能在 O ( 1 ) O(1) O(1)的时间内只用一次或几次就定位到。
一般用3种数据结构存储图:

  1. 即邻接矩阵
  2. 邻接表
  3. 链式前向星
    以如下的有向图为例
邻接矩阵:
邻接矩阵的定义方式

用二维数组存储即可: i n t   g r a p h [ N ] [ N ] int\ graph[N][N] int graph[N][N],每个节点 g r a p h [ i ] [ j ] graph[i][j] graph[i][j] 表示从 i i i j j j 的距离。
对于无向图有: g r a p h [ i ] [ j ] = g r a p h [ j ] [ i ] graph[i][j]=graph[j][i] graph[i][j]=graph[j][i]
对于有向图有: g r a p h [ i ] [ i ] ! = g r a p h [ j ] [ i ] graph[i][i]!=graph[j][i] graph[i][i]!=graph[j][i]
权值:如图则有: g r a p h [ 1 ] [ 2 ] = 3 、 g r a p h [ 2 ] [ 1 ] = 5 … … graph[1][2]=3、graph[2][1]=5…… graph[1][2]=3graph[2][1]=5……;用 g r a p h [ i ] [ j ] = + ∞ graph[i][j]=+\infty graph[i][j]=+表示 i i i j j j 之间无边。

优劣分析

优点:

  1. 编码非常简短。
  2. 适用于稠密图。
  3. 对边的存储、查询、更新等操作又快又简单,只需要一步就能访问和修改。
    缺点:
  4. 存储复杂度 O ( V 2 ) O(V²) O(V2)太高。如果用来存稀疏图,大量空间会被浪费。例如上面的图, 6 6 6个点,只有 11 11 11条边,但是 g r a p h [ 6 ] [ 6 ] graph[6][6] graph[6][6]的空间是 36 36 36。当 V = 10000 V=10000 V=10000个结点时,空间为 100 M B 100MB 100MB,已经超过了常见竞赛题的空间限制,而一百万个点的图在竞赛题中是很常见的。
  5. 一般情况下不能存储重边。 ( u , v ) (u,v) (u,v) 之间可能有两条或更多的边,这些边的费用不同、容量不同,是不能合并的。有向边 ( u , v ) (u,v) (u,v)在矩阵中只能存储一个参数,矩阵本身的局限性使它不能存储重边。
邻接表

邻接表是一种常用的图的存储方式,它可以用链表表示图的结构。在邻接表中,每个节点都对应一个链表,链表中存储了与该节点相连的所有节点。规模大的稀疏图一般用邻接表存储。

优劣分析

有点:

  1. 存储效率非常高,只需要与边数成正比的空间,存储复杂度为 O ( V + E ) O(V+E) O(V+E)
  2. 能存储重边。
    缺点:
  3. 编程比邻接矩阵麻烦。
  4. 访问和修改效率稍低稍慢。
实现代码
vector<int>G[N]; //邻接表  
void init(){ //初始化  
	for(int i = 0; i < N; i++)  
		G[i].clear();  
}  
void addEdge(int x, int y){ //插入路径:x -> y  
	G[x].push_back(y);  
}

对于上图所成的邻接表如下:

i = 1 i=1 i=124
i = 2 i=2 i=21345
i = 3 i=3 i=3 n u l l null null
i = 4 i=4 i=415
i = 5 i=5 i=526
i = 6 i=6 i=63
链式前向星

用邻接表存图非常节省空间,一般的大图也够用了。那如果空间极其紧张,有没有更紧凑的存图方法呢?邻接表有没有改进的空间?

分析邻接表的组成:存储一个结点 u u u 的邻接边,其方法的关键是先定位第 1 1 1个边,第 1 1 1个边再指向第 2 2 2个边,第 2 2 2个边再指向第 3 3 3个边……根据这个分析,可以设计一种极为紧凑、没有任何空间浪费、编码非常简单的存图方法。下图是对前面的图生成的存储空间,其中, h e a d [ N U M ] head[NUM] head[NUM]是一个静态数组, s t r u c t   e d g e struct\ edge struct edge是一个结构的静态数组,至少包含 t o 和 n e x t to和next tonext 两项元素。

以结点 2 2 2为例:
从点 2 2 2出发的边有 4 4 4条,即 ( 2 , 1 ) (2,1) (2,1) ( 2 , 3 ) (2,3) (2,3) ( 2 , 4 ) (2,4) (2,4) ( 2 , 5 ) (2,5) (2,5),邻居是 1 、 3 、 4 、 5 1、3、4、5 1345

  1. 定位第 1 1 1个边。用 h e a d [   ] head[\ ] head[ ]数组实现,例如 h e a d [ 2 ] head[2] head[2]指向结点 2 2 2的第 1 1 1个边, h e a d [ 2 ] = 8 head[2]=8 head[2]=8,它存储在 e d g e [ 8 ] edge[8] edge[8]这个位置。
  2. 定位其他边。用 e d g e edge edge n e x t next next参数指向下一个边。 e d g e [ 8 ] . n e x t = 6 edge[8].next=6 edge[8].next=6,下一个边在 e d g e [ 6 ] edge[6] edge[6]这个位置,然后 e d g e [ 6 ] . n e x t = 4 edge[6].next=4 edge[6].next=4 e d g e [ 4 ] . n e x t = 1 edge[4].next=1 edge[4].next=1,最后 e d g e [ 1 ] . n e x t = — 1 edge[1].next=—1 edge[1].next=—1,-1表示结束。

s t r u c t   e d g e struct\ edge struct edge t o to to参数记录这个边的邻居结点。例如 e d g e [ 8 ] . t o = 5 edge[8].to=5 edge[8].to=5,第一个邻居是点 5 5 5;然后 e d g e [ 6 ] . t o = 4 edge[6].to=4 edge[6].to=4 e d g e [ 4 ] . t o = 3 edge[4].to=3 edge[4].to=3 e d g e [ 1 ] . t o = 1 edge[1].to=1 edge[1].to=1,得到邻居是 1 、 3 、 4 、 5 1、3、4、5 1345
上述存储方法被称为“链式前向星”,它是空间效率最高的存储方法,因为它用静态数组模拟邻接表,没有任何浪费。

实现代码
const long long N = 1e7 + 6;    //百万节点百万边
struct Edge{
    int next, to, w;    //终点to,下一条边next,权值w
};
Edge edge[N];
int head[N];    //head[i]表示指向i节点的第一条边的位置
int cnt = 0;    //cnt记录的是edge的末尾,新加入的位置都在末尾
void init(){
    cnt = 0;
    for(int i = 0; i < N; i++){
        edge[i].next = -1;
        head[i] = -1;
    }
}
void addEdge(int u, int v, int w){
    //添加u到v边,权值为w
    edge[cnt].to = v;
    edge[cnt].w = w;
    edge[cnt].next = head[u];
    head[u] = cnt;
    cnt++;
}

for(int i = head[u]; i != -1; i = edge[i].next){
    //遍历i的所有邻居
}
优劣分析

优点:

  1. 存储效率高
  2. 程序简单
  3. 能存储重边
    缺点:
  4. 不方便做删除操作。可尝试自己编写删除的程序

图的遍历

图的遍历与之前提过的树遍历类似。但是用DFS(递归)来搜索图,比BFS更难理解,但是一旦理解之后,编程将十分便利。图论中的很多算法,例如拓扑排序、强连通分量等,都建立在DFS之上。
下面是DFS的示例程序,其中用vector邻接表来存图。

vector<int>G[N];    //G[i][j]表示点i和点j之间的距离
int vis[N];    //vis = 0 表示这个点没有被访问过
               //vis = 1 表示访问过了
               //vis = -1 表示正在被访问中(拓扑排序跳出死循环可用)
bool dfs(int u){
    vis[u] = 1;
    if(……){……;return true;}     //出现目标,返回正确
    if(……){……;return false;}    //处理并返回错误
    for(int i = 0; i < G[u].size(); i++){//u的邻居有G[u].size个
        int v = G[u][i];        //v是第i个邻居
        if(!vis[v]){            //没有访问过就从这里继续
            return dfs(v);
        }
    }
    {……………………}      //后续处理
}   
某个点的连通性

对需要的点执行 d f s dfs dfs,就能找到它连通的点。例如找图中 e e e 点的连通性,执行 d f s ( e ) dfs(e) dfs(e),访问过程见图结点上面的数字,顺序是 e → b → d → c → a e\rightarrow b\rightarrow d\rightarrow c\rightarrow a ebdca。递归返回的结果见结点下面画线的数字,顺序是 a → c → d → b → e a\rightarrow c\rightarrow d\rightarrow b\rightarrow e acdbe。虚线指向的结点表示不再访问,因为前面已经被访问过。

上面DFS的结果生成了一棵树,称为深搜优先生成树( d e p t h − f i r s t s p a n n i n g   t r e e depth-firstspanning\ tree depthfirstspanning tree),有以下概念:

  1. 树边:树上的边称为树边 ( t r e e   e d g e ) (tree\ edge) (tree edge)
  2. 回退边:虚线表示的边 ( a , b ) (a,b) (a,b)称为回退边 ( b a c k   e d g e ) (back\ edge) (back edge),它不在树上。
  3. 在这棵树上,从起点到其他任何一个点只有一条路径。如果是无向图生成的树,那么任意两个点之间只有一条路径。
拓扑排序

图的 B F S BFS BFS D F S DFS DFS的一个直接应用是拓扑排序。
在现实生活中,人们经常要做一连串事情,这些事情之间有顺序关系或者有依赖关系,在做一件事情之前必须先做另一件事,比如安排客人的座位、穿衣服的先后、课程学习的先后等。这些事情都可以抽象为图论中的拓扑排序。

1.拓扑排序的概念

设有 a 、 b 、 c 、 d a、b、c、d abcd等事情,其中 a a a 有最高优先级, b 、 c b、c bc 优先级相同, d d d 是最低优先级,表示为 a → ( b , c ) → d a→(b,c)→d a(b,c)d,那么 a b c d abcd abcd a c b d acbd acbd 都是可行的排序。把事情看成图的点,把先后关系看成有向边,问题转化为在图中求一个有先后关系的排序,这就是拓扑排序。如下图左所示。
显然,一个图能进行拓扑排序的充要条件是它是一个有向无环图( D A G DAG DAG)。有环图不能进行拓扑排序。

2.图的入度和出度

拓扑排序需要用到点的入度和出度的概念。

  1. 出度:以点 u u u 为起点的边的数量称为 u u u 的出度。
  2. 入度:以点 v v v 为终点的边的数量称为 v v v 的入度。
    一个点的入度和出度体现了这个点的先后关系:如果一个点的入度等于 0 0 0,则说明它是起点,是排在最前面的;如果它的出度等于 0 0 0,则说明它是排在最后面的。例如在上图右中,点 a 、 c a、c ac的入度为 0 0 0,它们都是优先级最高的事情; d d d 的出度为 0 0 0,它的优先级最低。
    拓扑排序可以有多个,例如上图右中的a和c,谁排在前面都可以: [ a , c , b , d ] 或 [ c , a , b , d ] [a,c,b,d]或[c,a,b,d] [a,c,b,d][c,a,b,d]都是合理的。 D F S DFS DFS B F S BFS BFS都可以实现拓扑排序
3.基于 B F S BFS BFS的拓扑排序

基于 B F S BFS BFS的拓扑排序有两种思路:1. 无前驱的顶点优先、2. 后继的顶点优先。
下面先讲解无前驱的顶点优先拓扑排序。其方法是先输出出度为 0 0 0 (无前驱,优先级最高)点,具体操作如下图所示,其中 Q Q Q B F S BFS BFS的队列:

步骤简述如下:

  1. 找到所有入度为 0 0 0 的点,放进队列,作为起点,这些点谁先谁后没有关系。如果找不到入度为 0 0 0的点,说明这个图不是 D A G DAG DAG,不存在拓扑排序。上图1中 a 、 c a、c ac的入度为 0 0 0,进队列。
  2. 弹出队首 a a a a a a的所有邻居点,入度减 1 1 1,把入度减为 0 0 0 的邻居点 b b b 放进队列,没有减为 0 0 0的点不能放进队列。如上图2。
  3. 继续上述操作,直到队列为空。内容见上图后续。队列输出 a c b d acbd acbd,而且包含了所有的点,这就是一个拓扑排序。
  4. 如果队列已空,但是还有点未进入队列,那么这些点的入度都不是 0 0 0,说明图不是 D A G DAG DAG,不存在拓扑排序。

以上是“无前驱”的思路。读者很容易发现,这个过程可以反过来执行,即“无后继的顶点优先”:从出度为 0 0 0(无后继,优先级最低)的点开始,逐步倒推。其示意图如下所示,请读者自己分析过程。最后输出的是逆序 [ d , b , c , a ] [d,b,c,a] [d,b,c,a]

复杂度分析

在初始化时,查找入度为 0 0 0的点,需要检查每个边,复杂度为 O ( E ) O(E) O(E);在队列操作中,每个点进出队列一次,需要检查它直接连接的所有邻居,复杂度是 O ( V + E ) O(V+E) O(V+E)。其总复杂度是 O ( V + E ) O(V+E) O(V+E)

4.基于 D F S DFS DFS搜索的拓扑排序

D F S DFS DFS天然适合拓扑排序。
回顾 D F S DFS DFS深度搜索的原理:沿着一条路径一直搜索到最底层,然后逐层回退。这个过程正好体现了点和点的先后关系,天然符合拓扑排序的原理。
一个有向无环 D A G DAG DAG图,如果只有一个点 u u u 0 0 0入度的,那么从 u u u开始 D F S DFS DFS D F S DFS DFS递归返回的顺序就是拓扑排序(是一个逆序)。 D F S DFS DFS递归返回的首先是最底层的点,它一定是 0 0 0出度点,没有后续点,是拓扑排序的最后一个点;然后逐步回退,最后输出的是起点 u u u;输出的顺序是一个逆序。

以上图为例,从 a a a 开始,递归返回的顺序见点旁边画线的数字,即 [ c , d , b , a ] [c,d,b,a] [c,d,b,a],是拓扑排序的逆序。为了按正确的顺序打印出拓扑排序,编程时的处理是定义一个拓扑排序队列 l i s t list list,每次递归输出的时候把它插到当前 l i s t list list的最前面,最后从头到尾打印 l i s t list list,就是拓扑排序。这实际上是一个栈,直接用STL的stack即可。

细节处理
  1. 应该以入度为 0 0 0的点为起点开始 D F S DFS DFS。如何找到它?需要找到它吗?如果有多个入度为 0 0 0的点呢?
    这几个问题其实并不用特别处理。想象有一个虚拟的点 v v v,它单向连接到所有其他点。这个点就是图中唯一的 0 0 0入度点,图中所有其他的点都是它的下一层递归,而且它不会把原图变成环路。从这个虚拟点开始 D F S DFS DFS就完成了拓扑排序。
    例如 图 ( a ) 图(a) (a)有两个 0 0 0入度点 a a a f f f 图 ( b ) 图(b) (b)想象有个虚拟点 v v v,那么递归返回的顺序见点旁边画线的数字,返回的是拓扑排序的逆序。

    在实际编程的时候并不需要处理这个虚拟点,只要在主程序中把每个点轮流执行一遍 D F S DFS DFS即可。这样做相当于显式地递归了虚拟点的所有下一层点。
  2. 如果图不是 D A G DAG DAG,能判断吗?
    图不是DAG,说明图是有环图,不存在拓扑排序。那么在递归的时候会出现回退边。如果读者不理解这一点,请回顾上一节的内容。在程序中这样发现回退边:记录每个点的状态,如果 d f s (   ) dfs(\ ) dfs( )递归到某个点时发现它仍在前面的递归中没有处理完毕,说明存在回退边,不存在拓扑排序。
  3. 如果要按照字典序输出同优先级的节点呢?只需要在 B F S BFS BFS中把队列换成优先队列即可。

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

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

相关文章

iptables配置NAT实现端口转发

加载防火墙的内核模块 modprobe ip_tables modprobe ip_nat_ftp modprobe ip_conntrack 1.开启路由转发功能 echo net.ipv4.ip_forward 1 >> /etc/sysctl.conf sysctl -p2、将本地的端口转发到本机端口 将本机的 7777 端口转发到 6666 端口。 iptables -t nat -A PR…

MySQL 高级 - 第十二章 | 数据库的设计规范

目录 第十二章 数据库的设计规范12.1 为什么需要数据库设计12.2 范式12.2.1 范式简介12.2.2 范式都包括哪些12.2.3 键和相关属性的概念12.2.4 第一范式&#xff08;1st NF&#xff09;12.2.5 第二范式&#xff08;2nd NF&#xff09;12.2.6 第三范式&#xff08;3rd NF&#xf…

图形编辑器基于Paper.js教程02:图形图像编辑器概述

背景 由于笔者目前从事开发图形编辑器&#xff0c;在开始的那段时间里&#xff0c;调研和研究了非常多的图形编辑器&#xff0c;图像编辑器之类的软件&#xff0c;开源&#xff0c;闭源的&#xff0c;免费的&#xff0c;商业的都有。今天的这篇文章就来简单概述一下我调研的结…

Nginx缓存之代理缓存配置

Nginx 的缓存功能是集成在代理模块中的&#xff0c;当启用缓存功能时&#xff0c;Nginx 将请求返回的响应数据持久化在服务器磁盘中&#xff0c;响应数据缓存的相关元数据、有效期及缓存内容等信息将被存储在定义的共享内存中。当收到客户端请求时&#xff0c;Nginx 会在共享内…

【系统架构设计师】三、数据库系统(事务并发|封锁协议|数据库安全|商业智能|SQL语句)

目录 一、事务并发 1.1 事务概述 1.2 并发控制 1.3 封锁 1.3.1 X 封锁和 S 封锁 1.3.2 三级封锁协议 二、数据库安全 2.1 备份(转储)与恢复 2.2 备份分类 2.3 数据库故障 三、商业智能 3.1 数据仓库 3.2 数据仓库的结构-OLAP 3.3 数据挖掘 3.4 分布式数据库 四…

MacOS - 启动台(LaunchPad)缺少应用软件图标

问题描述 MacOS 有时会遇到已安装的软件在启动台&#xff08;LaunchPad&#xff09;中找不到的 bug&#xff0c;这种情况在新安装软件时易出现。 原因分析 首先去访达&#xff08;Finder&#xff09;中的“应用程序”文件夹确认是否已安装某软件&#xff08;LaunchPad 中图标…

Centos7安装自动化运维Ansible

自动化运维Devops-Ansible Ansible是新出现的自动化运维工具&#xff0c;基于Python 开发&#xff0c;集合了众多运维工具&#xff08;puppet 、cfengine、chef、func、fabric&#xff09;的优点&#xff0c;实现了批量系统配置 、批量程序部署、批量运行命令 等功能。Ansible…

【云手机】数据安全如何保障?

安全办公&#xff0c;信息安全&#xff0c;这是企业使用云手机的初衷和目的&#xff0c;云手机在数据保密&#xff0c;远程办公等功能上有巨大的优势&#xff0c;也为企业提供了支持 首先就是云手机能够实现数据的集中管理和加密存储。所有办公相关的数据都存储在云端的安全服务…

植物大战僵尸杂交版2024最新手机版下载!功能全面升级,战斗更刺激!

植物大战僵尸杂交版2024——让游戏更加有趣&#xff01; 嘿&#xff0c;各位游戏爱好者们&#xff01;&#x1f31f;今天我要给你们介绍的是一个全新版本的植物大战僵尸——植物大战僵尸杂交版2024。这款游戏不仅保留了原版的经典元素&#xff0c;还增加了许多新的特性和玩法&a…

【Windows】Topaz Gigapixel AI(人工智能图片放大工具)软件介绍和安装教程

软件介绍 Topaz Gigapixel AI是一款由Topaz Labs开发的先进图像放大软件&#xff0c;利用人工智能&#xff08;AI&#xff09;技术来放大图像&#xff0c;同时保持或甚至增强图像的细节和清晰度。这款软件特别适用于需要高质量图像放大的摄影师、设计师以及其他视觉内容创作者…

电脑丢失dll文件一键修复的方法有哪些?分析dll文件修复的多种策略

我们经常会遇到各种各样的问题&#xff0c;其中之一就是DLL文件的丢失。DLL文件&#xff08;动态链接库&#xff09;是操作系统和应用程序正常运行所必需的文件&#xff0c;当这些文件丢失或损坏时&#xff0c;可能会导致软件无法正常启动&#xff0c;甚至影响系统的稳定性。对…

什么是拷贝?我:Ctrl + C ...

前言 当谈及拷贝&#xff0c;你的第一印象会不会和我一样&#xff0c;ctrl c ctrl v ... &#xff1b;虽然效果和拷贝是一样的&#xff0c;但是你知道拷贝的原理以及它的实现方法吗&#xff1f;今天就让我们一起探究一下拷贝中深藏的知识点吧。 拷贝 首先来看下面一段代码…

【机器学习】第11章 神经网络与深度学习(重中之重)

一、概念 1.神经元模型 &#xff08;1&#xff09;神经网络的基本组成单位 &#xff08;2&#xff09;生物上&#xff0c;每个神经元通过树突接受来自其他被激活神经元的信息&#xff0c;通过轴突释放出来的化学递质改变当前神经元内的电位。当神经元内的电位累计到一个水平时…

【Docker实战】jenkins卡在编译Dockerfile的问题

我们的项目是标准的CI/CD流程&#xff0c;也即是GitlabJenkinsHarborDocker的容器自动化部署。 经历了上上周的docker灾难&#xff0c;上周的服务器磁盘空间灾难&#xff0c;这次又发生了jenkins卡住的灾难。 当然&#xff0c;这些灾难有一定的连锁反应&#xff0c;是先发生的d…

2024 端午节巽寮湾游玩记录

2024 端午节巽寮湾游玩记录 文章目录 2024 端午节巽寮湾游玩记录一、前言二、巽寮湾游玩行程1、三天衣食住行2、主要图片&#xff1a; 三、其他1、小结2、巽寮湾游玩建议3、感慨 一、前言 时间总是过得很快&#xff0c;只要你活着时间就会不停往前走。 所以你以后的路其实都是…

【机器学习】 第1章 概述

一、概念 1.机器学习是一种通过先验信息来提升模型能力的方式。 即从数据中产生“模型”( model )的算法&#xff0c;然后对新的数据集进行预测。 2.数据集&#xff08;Dataset&#xff09;&#xff1a;所有数据的集合称为数据集。 训练集&#xff1a;用来训练出一个适合模…

Maven添加reactor依赖失败

目录 情况说明 解决过程 情况说明 起初是自己在学spring boot3&#xff0c;结果到了reactor这一部分的时候&#xff0c;在项目的pom.xml文件中添加下列依赖报错&#xff1a; <dependencyManagement><dependencies><dependency><groupId>io.projectr…

“Git掌控:分布式版本控制系统解析“

目录 # Git基础 1. Git下载 2. Git三种程序命令 2.1 Git Bash基本命令 2.2 Git更新项目命令 3. Git配置 3.1 设置用户名&#xff08;EE配置&#xff09; 3.2 查看用户名信息 4. Git基本理论 5. Git项目搭建 5.1 克隆远程仓库 5.2 指定本地克隆的目录 6. Git文件操…

【硬件开发】自举电路

为什么需要自举电路 半桥驱动电路中&#xff0c;下桥臂的源极直接接地&#xff0c;导通时栅极电压只需要达到MOS管导通d电压Vgs&#xff0c;但是对于上桥臂来说&#xff0c;上桥臂的源极电压会随着上桥臂的导通而抬升到VDD&#xff0c;对应想要导通时的栅极电压Vgs要到达VgsVDD…

代码随想录第20天|二叉树

654.最大二叉树 构造二叉树: 使用前序遍历 已理解思路 617.合并二叉树 虽然开辟额外空间, 但结果依旧受到原来的数影响(当为null时直接借用了原来数的节点) class Solution { public:TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {if (root1 nullptr) return roo…