当前位置: 首页 > news >正文

【算法-图论】图的存储

【算法-图论】图的存储

在图论中,我们应该如何存储一个图?每种存图的方法有什么优点,有什么缺点?这篇文章将会让你找到答案

1. 邻接表

邻接表是由一个静态的数组套动态的数组构成的。我们都知道动态数组的空间会随着数组的大小进行改变,可长可短,还可以自动释放一些无需的闲置空间,而外面的静态数组也可能对于一些节点空间小,一些节点空间大

当我们定义了一个邻接矩阵 GGG 时,GiG_iGi 则表示从 iii 号节点经过一条边到达的节点所构成的集合,我们只要遍历集合,就相当于遍历了以 iii 号为起点的边

在这里插入图片描述
例如上面的这个有向图可以写成这样的邻接表
G0={2,4,5}G1={4,5}G2={3,4}G3=∅G4={5}G5=∅ G_0 = \{2, 4, 5\} \\ G_1 = \{4, 5\} \\ G_2 = \{3, 4\} \\ G_3 = \emptyset \\ G_4 = \{5\} \\ G_5 = \emptyset G0={2,4,5}G1={4,5}G2={3,4}G3=G4={5}G5=
此外,如果这个图是无向图,可以看成两个相连的节点互相连接
在这里插入图片描述在这里插入图片描述
如果还想保存权值的话,就在里面的动态数组中套一个结构体,一个是要到的点,另一个是到那个点的边的权值

以下是对于有权值有向图的邻接表的代码

const int V = 1005; // 点的数量struct EdgeNode {int v, w; // 到的地方和权值
};vector<EdgeNode> G[V];void AddEdge (int u, int v, int w) {G[u].push_back({v, w});
}

2. 邻接矩阵

它使用的是要一个二维静态数组,Gu,vG_{u, v}Gu,v 表示从 uuuvvv 是否有边链接,如果有边为 111,否则没边为 000。对于有权值的边而言,Gu,vG_{u, v}Gu,v表示为从 uuuvvv 连接的边权,如果没边则 Gu,v=∞G_{u, v} = \inftyGu,v=,另外,Gi,i=0G_{i, i} = 0Gi,i=0
在这里插入图片描述

对于这个图,那么它的邻接矩阵就是:
[011110100100100010110001101001000110] \begin{bmatrix} 0 & 1 & 1 & 1 & 1 & 0 \\ 1 & 0 & 0 & 1 & 0 & 0 \\ 1 & 0 & 0 & 0 & 1 & 0 \\ 1 & 1 & 0 & 0 & 0 & 1 \\ 1 & 0 & 1 & 0 & 0 & 1 \\ 0 & 0 & 0 & 1 & 1 & 0 \\ \end{bmatrix} 011110100100100010110001101001000110

其中,我们不难发现:矩阵始终是个方阵,且大小为 ∣V∣2|V|^2V2

这是有权值无向图的邻接矩阵的写法:

const int V = 1005; // 点的个数int G[V][V]; // 邻接矩阵void AddEdge (int u, int v, int w) {G[u][v] = G[v][u] = w; 
}int main () {memset(G, 0x3f, sizeof(G));
}

3. 边表

边表,也叫做链式前向星,它使用一个大小 2∣E∣2|E|2∣E 的一维数组 EdgeEdgeEdge 存储边,还有一个大小为 ∣V∣|V|V 的数组 HeadHeadHead 表示头指针。其中,EdgeEdgeEdge 的每一个元素实际上存储了三个属性:边连接哪个点、边的权值和同样以这个边的起点作为起点的其他的边,用于遍历所有的边。HeadHeadHead 存储着应该从哪里开始遍历以某个点作为起点的所有点,作为遍历的开端。实际编程时,我们可以倒着连接

这是加边用的函数

const int ARRMAX = 100005;struct GrephEdge {int v; // 去哪个点int w; // 权值int nxt; // 下一个边
} Edge[ARRMAX << 1];
int cnt; 
int Head[ARRMAX];void AddEdge (int u, int v, int w) { // 插入以 u 为起点,v 为终点,权值为 w 的边Edge[cnt] = {v, w, Head[u]}; // 边的增加Head[u] = cnt++; // 改变头指针
}
http://www.xdnf.cn/news/1183573.html

相关文章:

  • Langchain学习——PromptTemplate
  • 关于“PromptPilot”
  • 【大模型实战】提示工程(Prompt Engineering)
  • Tomcat线程池深度优化指南:高并发场景下的maxConnections计算与监控体系
  • 门店管理智能体,为连锁运营开出健康“处方” 智睿视界
  • DeepSeek FlashMLA 技术拆解,AI 推理迎来颠覆性突破
  • [linux]Haproxy七层代理
  • [实战] 用1 PPS 驯服本地恒温晶振(OCXO/TCXO)
  • Kubernetes深度解析:企业级容器编排平台的核心实践
  • Android 10.0 sts CtsSecurityBulletinHostTestCases的相关异常分析
  • 力扣 hot100 Day55
  • JAVA知识点(六):性能调优与线上问题排查
  • 多场景通用车辆计数算法助力暑期交通管理
  • [LeetCode]每日温度
  • Photon v0.3.0 基于Aria2免费开源轻量级多线程不限速下载器
  • Linux 桌面市场份额突破 5%:开源生态的里程碑与未来启示
  • 云原生介绍
  • Qt 状态机框架:复杂交互逻辑的处理
  • 滚动提示组件
  • JavaScript 数组的 every() 和 some() 方法使用
  • Microsoft-DNN NTLM暴露漏洞复现(CVE-2025-52488)
  • JAVA知识点(三):Spring与ORM框架
  • Linux下使用VSCode配置GCC环境与调试指南
  • 深入探索嵌入式仿真教学:以酒精测试仪实验为例的高效学习实践
  • 验证 GitHub Pages 的自定义域(Windows)
  • 《Uniapp-Vue 3-TS 实战开发》自定义年月日时分秒picker组件
  • SaaS型小程序自动化发布解决方案
  • VoWiFi技术深度解析:架构、流程与演进
  • 深入解析HBase如何保证强一致性:WAL日志与MVCC机制
  • 如何在 Ubuntu 24.04 或 22.04 上安装和使用 GDebi