【数据结构】邻接表 vs 邻接矩阵:5大核心优势解析与稀疏图存储优化指南
邻接表法
- 导读
- 一、邻接矩阵的不足
- 邻接表
- 二、存储结构
- 三、算法评价
- 3.1 时间复杂度
- 3.2 空间复杂度
- 四、邻接表特点
- 4.1 特点解读
- 特点3
- 特点4
- 特点5
- 结语
导读
大家好,很高兴又和大家见面啦!!!
图作为一种复杂的数据结构,其高效存储与操作一直是算法设计的核心问题。邻接矩阵虽能快速判断顶点间关系,但在稀疏图中却面临空间浪费严重的瓶颈。为此,邻接表(Adjacency List)应运而生——它通过为每个顶点维护邻居链表,以空间复杂度 (O(V+E)) 的灵活结构,成为稀疏图、动态图及大规模图场景下的理想选择。
本文从邻接矩阵的不足切入,逐步剖析邻接表的设计思想、存储结构(顶点表与边表)与代码实现(C语言示例),并通过时间复杂度、空间复杂度对比,揭示其性能优势。同时,深入解读邻接表的五大核心特点:
- 如何高效遍历邻居?
- 为何判断边存在性效率较低?
- 有向图与无向图在入度、出度计算上的差异;
- 邻接表为何不具备唯一性?
- 稀疏图场景下为何更优?
无论您是初学图论,还是需优化图算法效率,本文将为理解邻接表提供清晰的路径,助您在工程实践中精准选择数据结构,平衡时空效率。
一、邻接矩阵的不足
在邻接矩阵法中,我们通过一维数组存储图中的顶点信息,二维数组存储图中的边的信息。
对于稠密图这种边的数量较多的图而言,邻接矩阵是一个非常实用的存储结构。
通过空间换时间的操作,能够快速的找到两个顶点之间是否存在将其连通的边或者弧。
但是因为邻接矩阵中不仅记录了已有边的信息,还记录了不存在的边的信息,这就导致我们在计算图中边的总数时,会花费大量的时间。
在这种情况下,像稀疏图这种边的数量很少的图,通过邻接矩阵进行存储边的信息,就不是那么的合适。
为了优化邻接矩阵中对空间浪费的问题,我们可以采用链表的方式来存储图中的边,以达到减少空间的损耗。
通过一维数组存储顶点信息,链表存储边的信息共有3中存储结构:
- 邻接表法
- 十字链表
- 邻接多重表
接下来我们就来认识以下第一种存储结构——邻接表法(Adjacency List Method)。
邻接表
所谓的邻接表,是指对图 G G G 中的每个顶点 v i v_i vi 都建立一个单链表,第 i i i 个链表中的结点表示依附于顶点 v i v_i vi 的边(对于有向图则是以顶点 v i v_i vi 为弧尾的弧),这个单链表就称为顶点的边表 (对于有向图则称为出边表)。边表的头指针和顶点的数据信息采用顺序存储,称为顶点表。
在邻接表中存在两种结点:
- 顶点表结点:
- 顶点域:存储顶点信息
- 边表头指针:指向第一条边的边表结点
- 边表结点:
- 邻接点域:存储与头结点邻接顶点的顶点编号
- 指针域:指向下一条边的边表结点
在邻接表中,每个顶点所对应的边表,都记录了与该顶点邻接的其它顶点的编号信息,我们通过该编号信息就能够从顶点表中找到该顶点的信息,从而获取当前边的信息。
就比如,上图中存储的是无向图,顶点A的第一个边表结点中邻接点域存放的编号为1,那么,我们通过查询顶点表中的编号即可得到该顶点为B,因此我们就得到了依附于顶点 A , B A, B A,B 的边 ( A , B ) (A, B) (A,B) ;
当存储的是有向图时,此时边表中记录的是弧尾顶点的编号信息,那么我们由该编号信息获取到该顶点信息时,这个顶点就是弧的弧尾。
如上图所示,当我们从顶点a的出边表头指针找到第一个邻接的顶点编号信息时,我们再通过顶点表获取到了该顶点为 b,此时我们就得到了有向图的一条从a到b的弧 < a , b > <a, b> <a,b>;
二、存储结构
在邻接表中,我们需要单独定义顶点表结点与边表(出边表)结点,对应的C语言存储结构如下所示:
typedef char VertexType;
typedef int AdjVexType;
#define MAXSIZE 5
//边表结点
typedef struct EdgeNode {AdjVexType adjvex; // 邻接顶点编号struct EdgeNode* nextarc; // 下一个边表结点
}EdgeNode; // 边表结点
//顶点表结点
typedef struct VexNode {VertexType data; // 顶点信息EdgeNode* firstarc; // 边表头指针
}VexNode; // 顶点表结点
//邻接表
typedef struct Adjacency_List_Method_Graph {VexNode vexlist[MAXSIZE]; // 顶点表int vexnum; // 当前顶点数int edgenum; // 当前边数
}ALGraph; // 邻接表
三、算法评价
3.1 时间复杂度
在邻接表中,我们在进行遍历时,实际上就是完成了一次顺序表的遍历以及每个顺序表所附带的链表的遍历,因此其时间复杂度是有顺序表的遍历与链表的遍历综合来看:
- 顺序表的遍历时间复杂度为 O ( ∣ V ∣ ) O(|V|) O(∣V∣) ,这里的 ∣ V ∣ |V| ∣V∣ 为顶点的数量
- 链表的遍历时间与边被记录的次数有关:
- 在无向图中,由于边会被记录两次,所以遍历时间复杂度为 O ( ∣ 2 E ∣ ) O(|2E|) O(∣2E∣)
- 在有向图中,边只会被记录一次,所以遍历时间复杂度为 O ( ∣ E ∣ ) O(|E|) O(∣E∣)
因此总的时间复杂度为 :
- 无向图: T ( N ) = O ( ∣ V ∣ + 2 ∣ E ∣ ) T(N) = O(|V| + 2|E|) T(N)=O(∣V∣+2∣E∣);
- 有向图: T ( N ) = O ( ∣ V ∣ + ∣ E ∣ ) T(N) = O(|V| + |E|) T(N)=O(∣V∣+∣E∣);
3.2 空间复杂度
在邻接表中,我们需要为顶点和边分别申请空间:
- 顶点申请的空间数量由顶点个数决定,即空间复杂度为 O ( ∣ V ∣ ) O(|V|) O(∣V∣)
- 边申请的空间数量由边个数决定
- 在无向图中,每条边都需要被记录两次,因此对应的空间复杂度为 O ( ∣ 2 E ∣ ) O(|2E|) O(∣2E∣)
- 在有向图中,每条边只需要被记录一次,因此对应的空间复杂度为 O ( ∣ E ∣ ) O(|E|) O(∣E∣)
记录顶点与边数量的变量所占用的空间是固定的,其对应的空间复杂度为 O ( 1 ) O(1) O(1) ,在总的空间复杂度中可以忽略不计。
因此在无向图中总的空间复杂度为 T ( N ) = O ( ∣ V ∣ + ∣ 2 E ∣ ) T(N) = O(|V| + |2E|) T(N)=O(∣V∣+∣2E∣);在有向图中总的空间复杂度为 T ( N ) = O ( ∣ V ∣ + ∣ 2 E ∣ ) T(N) = O(|V| + |2E|) T(N)=O(∣V∣+∣2E∣)
四、邻接表特点
图的邻接表存储具有以下特点:
- 若G为无向图,则所需要的存储空间为 O ( ∣ V ∣ + 2 ∣ E ∣ ) O(|V| + 2|E|) O(∣V∣+2∣E∣) ;若为有向图,则所需的存储空间为 O ( ∣ V ∣ + ∣ E ∣ ) O(|V| + |E|) O(∣V∣+∣E∣).
- 对于稀疏图(边数较少的图),采用邻接表表示将极大地节省存储空间
- 在邻接表中,给定一个顶点,能很容易地找到它的所有邻边,因为只需要读取它的邻接表。在邻接矩阵中,相同的操作则需要扫描一行,花费的时间为 O ( N ) O(N) O(N) 。但是,若确定给定的两个顶点之间是否存在边,则在邻接矩阵中能快速查到,而在邻接表中则需要再相应顶点对应的边表中查找另一结点,效率极低。
- 在无向图的邻接表中,求某个顶点的度秩序计算其邻接表中的边表结点个数。在有向图的邻接表中,求某个顶点的出度只需要计算其邻接表中的边表结点个数;但求某个顶点 x 的入度则需遍历全部的邻接表,统计邻接点域为 x 的边表结点个数。
- 图的邻接表表示并不唯一,因为在每个顶点对应的边表中,各边结点的链接次序是任意的,它取决于建立邻接表的算法及边的输入次序。
4.1 特点解读
邻接表的特点的前两点都很好理解,这里我就不再赘述。下面我们重点要理解后面的三点:
特点3
在邻接表中,给定一个顶点,能很容易地找到它的所有邻边,因为只需要读取它的邻接表。
这个点可能有朋友不太理解,为什么我们是需要读取邻接表而不是读取边表?
这是因为邻接表是有顶点表和边表组成,而边表中记录的是邻接顶点的定点表编号,如果我们是统计给定顶点边的个数,那么只看该顶点的边表即可,但是我们要想找到所有的边,那么就需要借助边表找到邻接顶点的编号,再由顶点表读取顶点信息才行,因此我们是读取的整个邻接表,而不是单一的边表。
在邻接矩阵中,相同的操作则需要扫描一行,花费的时间为 O ( N ) O(N) O(N) 。
这个点可能有朋友会奇怪,在顶点表中,我们也是扫描的边表,按理来说应该花费的时间也是 O ( N ) O(N) O(N) 呀,这两者有什么区别吗?
这是因为邻接矩阵中不管两个顶点之间是否存在边,每一行它都是 N N N 个空间,但是在邻接表中,只记录了与该顶点邻接的顶点编号,这个数量一定不会超过 N N N ,在大多数情况下,这个数量一定是小于 N N N 的,因为我们使用邻接表存储时,肯定是用于存储的稀疏图。
但是,若确定给定的两个顶点之间是否存在边,则在邻接矩阵中能快速查到,而在邻接表中则需要再相应顶点对应的边表中查找另一结点,效率极低。
在邻接矩阵中,我们只要知道了两个顶点的信息,我们就能通过点 a i j a_{ij} aij 的值来判断这两个点之间是否存在边,查找效率为 O ( 1 ) O(1) O(1);
但是在邻接表中,不管是存储的有向图还是无向图,我们至少都要遍历一个顶点的边表,如果是有向图,最坏情况下,两个顶点的边表我们都需要遍历,因此查找的效率为 O ( M ) ( M ≤ N ) O(M)(M \leq N) O(M)(M≤N)
特点4
在无向图的邻接表中,求某个顶点的度只需计算其邻接表中的边表结点个数。
在无向图的邻接表中,边表的结点个数就是与该顶点邻接的顶点的个数,也就是该顶点的度数。
在有向图的邻接表中,求某个顶点的出度只需要计算其邻接表中的边表结点个数;
在有向图的邻接表中,出边表中记录的是以该顶点为边尾的顶点数量,即该顶点的出度数;
但求某个顶点 x 的入度则需遍历全部的邻接表,统计邻接点域为 x 的边表结点个数。
在有向图中,对于一个顶点的入度数,我们无法通过自身的边表获取,只能够通过其它顶点的边表获取。
- 如果在其它顶点中找到了存储该顶点的编号信息的出边表结点,那就说明该顶点存在一条入度;
- 若在其它顶点中未找到存储该顶点的编号信息的出边表结点,那就说明此时查找的顶点没有弧是指向该顶点的;
特点5
图的邻接表表示并不唯一,因为在每个顶点对应的边表中,各边结点的链接次序是任意的,它取决于建立邻接表的算法及边的输入次序。
这个特点我们需要理解什么是唯一,在邻接矩阵中,矩阵中的信息是无法改变的,即我不管如何存储边的信息,它所对应的邻接矩阵是唯一的,有变化的无非就是矩阵中存储的值的变化;
但是在邻接表中,顶点表是不会改变,边表则是会变的:
- 在输入的顶点顺序一致时,如果我们在存储边表信息时,采用头插法存储和尾插法存储所得到的边表是不一样的;
- 在存储算法一致时,我们先输入顶点 a 的编号再输入顶点 b的编号与先输入顶点 b 的编号再输入顶点 a 的编号,此时得到的边表也是不一样的
因此我们说邻接表的表示不是唯一的,这个不唯一性就体现在边表上;
结语
邻接表以“顶点表+边表”的链式结构,完美解决了邻接矩阵在稀疏图中的空间浪费问题,其核心优势可总结为以下几点:
- 空间高效:存储复杂度仅 (O(V+E)),尤其适合边数较少的稀疏图;
- 动态灵活:快速增删边,适应图结构频繁变化的场景;
- 邻居遍历高效:直接访问边表,时间复杂度与顶点的实际度数相关,避免邻接矩阵的全行扫描;
- 支持复杂操作:天然适配DFS、BFS、最短路径等需要频繁遍历邻居的算法。
然而,邻接表并非完美:
• 边存在性判断效率低(需遍历链表);
• 有向图入度计算复杂度高(需遍历全表);
• 邻接表表示不唯一,依赖输入顺序和存储逻辑。
实际应用中,邻接表与邻接矩阵的取舍需基于图密度与操作需求:稀疏图优先邻接表,稠密图或频繁边查询场景倾向邻接矩阵。
理解邻接表的设计哲学——“按需存储,避免冗余”,将帮助开发者在算法优化与工程实践中找到时空效率的最佳平衡点。
如果本文对您有所启发,欢迎:
• 点赞👍 支持原创技术分享;
• 收藏📚 方便随时回顾;
• 转发🚀 让更多开发者受益!
关注我,持续解锁数据结构与算法的深度解析! 🌟
相关文章:
【数据结构】邻接表 vs 邻接矩阵:5大核心优势解析与稀疏图存储优化指南
邻接表法 导读一、邻接矩阵的不足邻接表二、存储结构三、算法评价3.1 时间复杂度3.2 空间复杂度 四、邻接表特点4.1 特点解读特点3特点4特点5 结语 导读 大家好,很高兴又和大家见面啦!!! 图作为一种复杂的数据结构,其…...
编程能力的跃迁时刻:技术革命与认知重构的交响曲
在软件开发领域,从业者常将"一万小时定律"视为能力增长的圭臬,但真正的能力跃迁往往发生在特定技术范式转换的临界点。当开发者首次理解递归算法的本质,当面向对象编程替代过程式思维,当自动化工具链重塑开发流程,这些认知地震时刻往往成为技术生涯的分水岭。 …...
PostIn V1.0.8版本发布,IDEA 插件支持一键扫描上报,让接口定义不再繁琐
PostIn是一款国产开源免费的接口管理工具,包含项目管理、接口调试、接口文档设计、接口数据MOCK等模块,支持常见的HTTP协议、websocket协议等,支持免登陆本地接口调试,同时可以对项目进行灵活的成员权限、消息通知管理等。本周Pos…...
删除Linux服务器上多余的系统启动项,并重装Ubuntu系统
问题描述 2024年6月,Centos团队终止维护Centos7系统,Ubuntu成了我的替换方案。正好有一台闲置的服务器,于是我临危受命给这台服务器重装系统。 经过我一番研究,Ubuntu系统初步安装成功了,但是存在一大堆问题ÿ…...
在亚马逊云科技上使用n8n快速构建个人AI NEWS助理
前言: N8n 是一个强大的工作流自动化工具,它允许您连接不同的应用程序、服务和系统,以创建自动化工作流程,并且采用了开源MIT协议,可以放心使用,他的官方网站也提供了很多的工作流,大家有兴趣的…...
JSON介绍及使用
1.JSON 1.JSON简介 JSON(JavaScript Object Notation)是一种轻量级的数据序列化协议,基于文本,完全独立于语言。 JSON由键值对组成,支持以下几种数据类型: 字符串:用双引号括起来的文本。 数…...
AOP 的织入过程是怎样的?
AOP(面向切面编程)的织入(Weaving)是将切面(Aspect)应用到目标对象(Target Object)并创建代理对象(Proxy Object)的过程。这个过程可以发生在不同的阶段&…...
链路聚合配置命令
技术信息 加入捆绑组,加大链路间带宽等 配置命令 华三 静态聚合 将接口加入聚合口后再进行配置 //创建静态链路聚合口1,不启用lacp[SWB]interface Bridge-Aggregation 1 [SWB-Bridge-Aggregation1]port link-type trunk [SWB-Bridge-Aggregation…...
为什么有的深度学习训练,有训练集、验证集、测试集3个划分,有的只是划分训练集和测试集?
在机器学习和深度学习中,数据集的划分方式取决于任务需求、数据量以及模型开发流程的严谨性。 1. 三者划分:训练集、验证集、测试集 目的 训练集(Training Set):用于模型参数的直接训练。验证集(Validati…...
【读书笔记·VLSI电路设计方法解密】问题61:扫描插入的目的是什么
如问题60所述,要构建可测试电路,必须确保电路中每个节点都具有可控性和可观测性。但对于包含时序元件(如触发器、锁存器等存储元件)的电路,若不采取特殊设计则难以实现这两项特性。这是因为时序元件关联节点的逻辑状态不仅取决于当前输入,还受其先前存储状态影响——它们…...
通信数据记录仪-产品概念ID
总结: 1、支持高速CAN、支持容错CAN、支持单线CAN(理解是支持不同的协议,CANFD、CAN2.0和LIN?) 2、 通过上位机设计时间...
【数据分享】2002-2023中国湖泊水位变化数据集(免费获取)
湖泊水位变化是研究水资源动态、生态系统演变和气候变化影响的重要指标。湖泊水位的升降不仅反映了降水、蒸发和入流水量的变化,还与人类活动、气候波动及地质过程密切相关。因此,高精度、长时间序列的湖泊水位数据对于水资源管理、洪水预测以及生态环境…...
SQL注入重新学习
前话 sql注入一般就是构造闭合,在查询语句中构造恶意语句,因为过滤并不严格导致信息泄露, 后台登陆语句:SELECT * FROM admin WHERE Username‘user’ and Password‘pass’ 万能密码:‘or ’1‘ ’1‘ # ; sql常用…...
修改Jupyter Notebook主目录文件夹
1、找到Jupyter Notebook配置文档 在anaconda prompt终端输入以下命令,可以显示配置文档所在位置: jupyter notebook --generate-config2、修改Jupyter Notebook主目录文件夹 用记事本打开文件夹中的jupyter_notebook_config.py文件。 在记事本中使用…...
玩转JSONObject:使用方法详解与Map对比
一、初识JSONObject 什么是JSONObject? JSONObject是Java中处理JSON数据的核心工具类,主流JSON库均提供类似实现: org.json(原生包)com.alibaba.fastjson.JSONObjectnet.sf.json.JSONObject 基础创建姿势 <JAV…...
LC416 vector<bool> 和 bool[] 的异同
LeetCode 416 1. 报错代码 // 01背包,从n个数字里面选,能否凑出和为s的方案 class Solution { public:bool canPartition(vector<int>& nums) {int m accumulate(nums.begin(), nums.end(), 0);if(m & 1) return false;m >> 1;…...
(51单片机)矩阵按键密码锁表白(C语言代码编撰)(矩阵按键教程)(LCD1602浅教程)
目录 源代码 main.c MatrixKey.c MatrixKey.h LCD1602.c LCD1602.h Delay.c Delay.h 运行效果图: 第一步: 第二步: 第三步: 第四步: 代码解析与教程: 延时函数Delay LCD1602 MatrixKey模块 源代…...
C++20新增内容
C20 是 C 语言的一次重大更新,它引入了许多新特性,使代码更现代化、简洁且高效。以下是 C20 的主要新增内容: 1. 概念(Concepts) 概念用于约束模板参数,使模板编程更加直观和安全。 #include <concept…...
思维链、思维树、思维图与思维森林在医疗AI编程中的应用蓝图
在医疗AI编程中,思维链(Chain of Thought, CoT)、思维树(Tree of Thoughts, ToT)、思维图(可能指知识图谱或逻辑图)以及思维森林(Forest-of-Thought, FoT)等技术框架通过模拟人类认知和推理过程,显著提升了AI在复杂医疗场景中的决策能力和可解释性: 1. 思维链(CoT)…...
[GN] Python3基本数据类型 -- 与C的差异
文章目录 前言Python3的基本数据类型6个标准的数据类型NumbersStringListtupleSetsDictionaries Python运算符逻辑 运算符成员运算符身份运算符 Python3 数字Python3 序列序列切片序列相加序列相乘序列相关内置函数 Python3 列表访问列表的值更新列表删除列表元素拼接列表嵌套列…...
TCP基础篇(一)
文章目录 1.TCP 是如何保证可靠性的?2. 滑动窗口机制3 超时重传4.TCP 报文格式5. 什么是 TCP 协议5.1 如何唯一确定一个 TCP 连接 6.TCP 三次握手过程6.1 可以两次握手吗? 7.TCP 的四次挥手7.1 为什么客户端要等待2MSL? 8.linux 中查看 TCP 的连接9.TCP 为什么要有…...
Spring-IOC部分
Spring-IOC部分 1.SpringBean的配置详解(Bean标签) (1)scope 默认情况下,单纯的Spring环境Bean的作用范围有两个:Singleton和Prototype singleton:单例,默认值,Spring…...
使用GitHub Actions构建CI/CD流程
GitHub Actions 简介 GitHub Actions 是一种自动化软件开发工作流的方式,与 GitHub.com 深度集成。开发人员可以通过配置 GitHub Actions 来实现基于事件触发的自动工作流,比如,当有任意用户向 master 分支提交代码时,自动执行一…...
Ubuntu服务器 无法正常启动redis
当我们在阿里云服务器上启动redis服务 运行下述命令时 service redis-server start 会出现如下报错 Failed to start redis-server.service: Unit redis-server.service not found. 如图: 解决方案: 通过以下命令重新安装Redis: sudo apt…...
MySQL 索引原理
一、索引基础概念 1. 索引是什么? 定义:索引是帮助MySQL高效获取数据的有序数据结构,类似书籍的目录。核心作用:减少磁盘I/O次数,提升查询速度(以空间换时间)。 2. 索引的优缺点 优点缺点加…...
前端快速入门学习3——CSS介绍与选择器
1.概述 CSS全名是cascading style sheets,中文名层叠样式表。 用于定义网页样式和布局的样式表语言。 通过 CSS,你可以指定页面中各个元素的颜色、字体、大小、间距、边框、背景等样式,从而实现更精确的页面设计。 HTML与CSS的关系:HTML相当…...
WPF 免费UI 控件HandyControl
示例效果和代码 直接可以用 Button 按钮 | HandyOrg 1.安装 , 输入 HandyControl 2.<!--配置HandyControl--> <!--配置HandyControl--> <ResourceDictionary Source"pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml"/> …...
【代码艺廊】pyside6桌面应用范例:homemade-toolset
在研发测试日常工作中,通常会遇到很多琐碎的事情,占用我们工作的时间和精力,从而导致我们不能把大部分的注意力放在主要的工作上面。为了解决这个问题,除了加人之外,我们通常会开发一些日常用的效率工具,比…...
Hive 常见面试 300 问
一、Hive 基础概念 什么是 Hive?它的主要用途是什么? Hive 与传统关系型数据库有什么区别? 简述 Hive 的架构,各个组件的作用是什么? 解释 Hive 中的元数据,它存储在哪里? Hive 支持哪些数据格式?各自的特点是什么? 什么是 Hive 表的分区?为什么要使用分区? 什么是 …...
OpenMinus 源码深度解析:从 React 模式到多智能体架构实现
OpenMinus 源码深度解析:从 React 模式到多智能体架构实现 本文基于 2024 年 3 月 9 日最新代码版本解析,完整代码已上传至 GitHub(附项目地址https://github.com/mannaandpoem/OpenManus) 一、项目背景与核心价值 1.1 项目定位 …...
【Linux网络与网络编程】04.TCP Socket编程
一、TCP Socket编程接口 // 创建套接字 int socket(int domain, int type, int protocol); // 参数: // domain:域(协议家族),这里使用 AF_INET 表示进行网络编程 // type:网络通信传输的类型࿰…...
初识数据结构——算法效率的“两面性”:时间与空间复杂度全解析
📊 算法效率的“两面性”:时间与空间复杂度全解析 1️⃣ 如何衡量算法好坏? 举个栗子🌰:斐波那契数列的递归实现 public static long Fib(int N) {if(N < 3) return 1;return Fib(N-1) Fib(N-2); }问题…...
CCF GESP C++编程 八级认证真题 2025年3月
C 八级 2025 年 03 月 题号 1 2 3 4 5 6 7 8 答案 B C B A D D D 一、单选题 第 1 题 国家“以旧换新”政策仍在继续,小杨家决定在家里旧的冰箱、电视、洗衣机、微波炉中选两种换新。其中,冰箱有4种型号可选,电视有6种型号可选,…...
React: hook相当于函数吗?
一、Hook 是一个函数,但不仅仅是函数 函数的本质 Hook 确实是一个 JavaScript 函数,例如 useState、useEffect 或自定义 Hook 都是函数。它们可以接受参数(如初始状态值或依赖项数组),并返回结果(如状态值和…...
Git 从入门到精通(开源协作特别版)
🧠 Git 从入门到精通(开源协作特别版) ✅ 基础命令 🧰 高级用法 🛠️ 开源实战技巧 🌍 GitHub 社区协作 适合:从0开始 → 熟练开发者 → 参与/维护开源项目 🔰 第1章:…...
《探索边缘计算:重塑未来智能物联网的关键技术》
最近研学过程中发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击链接跳转到网站人工智能及编程语言学习教程。读者们可以通过里面的文章详细了解一下人工智能及其编程等教程和学习方法。下面开始对正文内容的…...
什么是缓存穿透、缓存雪崩、缓存击穿?
什么是缓存? 缓存就是数据交换的缓冲区,是存贮数据的临时地方,一般读写性能较高。 怎么防止缓存穿透? 缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会打到…...
洛谷题单3-P4956 [COCI 2017 2018 #6] Davor-python-流程图重构
题目描述 在征服南极之后,Davor 开始了一项新的挑战。下一步是在西伯利亚、格林兰、挪威的北极圈远征。 他将在 2018 年 12 月 31 日开始出发,在这之前需要一共筹集 n 元钱。 他打算在每个星期一筹集 x 元,星期二筹集 xk 元,……...
解决浏览器报错Mixed Content
前端代码写死了访问后端的请求为:http://service.xxx.com:8080/api/,前端代码中混合内容(Mixed Content) 导致的。浏览器使用https访问站点时,这个请求会被拦截,并且浏览器打印 login.vue:151 Mixed Conten…...
HCIP【BGP协议(详解)】
目录 1 BGP协议产生背景 2 BGP协议特性 2.1 自治系统间路由传播 2.2 路由矢量协议 2.3 防环机制 2.4 基于TCP传输 2.5 路由更新机制 2.6 丰富的路由属性 2.7 支持CIDR和路由聚合 2.8 路由过滤和策略控制 2.9 动态对等体功能 3 BGP基本术语 4 BGP规划问题 4.1 路…...
集合与容器:List、HashMap(II)
一、ArrayList 是集合框架中最核心的动态数组实现,高频使用的容器之一。 1. 核心数据结构 基于数组实现,维护elementData数组存储元素: transient修饰的elementData不会被默认序列化(通过自定义序列化逻辑优化存储)…...
mac 安装MySQL
1、打开官网,点击Downloads 2、在downloads页面选择MySQL Community Server 3、选择对应的设备和版本,点击下载 4、下载选择 5、下载完成后,点击安装 6、next 到Configguration 时要输入密码(千万别忘记) 7.最后输…...
Pascal语言的软件开发工具
使用Pascal语言的软件开发工具 引言 随着计算机科学的发展,编程语言层出不穷,程序员们在开发时可以选择多种多样的工具。而Pascal语言作为一种历史悠久的程序设计语言,尽管在当今编程语言的生态中已不再是主流,但其优雅的语法和…...
vue组件开发:什么是VUE组件?
什么是VUE组件 在我们实际开发过程中你也许会发现有很多代码是重复的,它们可能是一个按钮、一个表单、一个列表等等,其中最为显著的应该是列表。 以CSDN的首页为例: 上述截图中的文章列表可能会在多处出现,比如此截图是精选博客…...
如何在Springboot的Mapper中轻松添加新的SQL语句呀?
在如今的软件开发界,Spring Boot可是非常受欢迎的框架哦,尤其是在微服务和RESTful API的构建上,真的是让人爱不释手!今天,我们就来聊聊如何为Spring Boot项目中的Mapper添加新的SQL语句吧!说起来࿰…...
微服务架构: SpringCloud服务注册与发现详解
# 微服务架构: SpringCloud服务注册与发现详解 一、什么是微服务架构 微服务架构简介 微服务架构(Microservices Architecture)是一种以一组小型服务应用程序构建系统的软件架构风格。每个服务运行在自己的进程中,通过精简的HTTP API进行通信…...
现代简约杂志海报包装网页设计无衬线英文字体安装包 Seriusans – Condensed Sans Display Font
Seriusans 是一种 Condensed Sans Display 字体,将现代简约与大胆融为一体。其狭窄而醒目的字体营造出强大的存在感,使其成为有影响力设计的绝佳选择,例如海报、杂志标题、品牌、包装、网页设计、运动图形、社论布局、广告活动、企业演示&…...
C/C++的条件编译
一、什么是条件编译? 条件编译是指在编译阶段根据某些条件来决定是否编译某段代码。这通常通过预处理指令来实现,比如 #if、#ifdef、#ifndef、#else、#elif 和 #endif。 二、为什么使用条件编译? 跨平台开发:不同的操作…...
视野,,地面覆盖,重叠需求,FPS,飞行速度等的计算公式
一、计算相机视野与重叠需求 1. 相机参数 IDS UI-5280CP: 分辨率:2456x2054 像素。传感器:假设为 1/1.8" CMOS(常见型号),尺寸约 6.78 mm(宽) 5.67 mm(高…...
ARXML文件解析-1
目录 1 摘要2 ARXML文件2.1 作用及典型应用场景2.2 **ARXML文件的结构树**2.3 TAG(XML元素)2.4 ARXML文件关键元素解析2.4.1 XML声明与处理指令2.4.2 XML注释2.4.3 ADMIN-DATA元素2.4.3 语言相关元素2.4.5 AR-PACKAGE体系结构2.4.6. 数据转换框架2.4.7 S…...