697 字
3 分钟
图的存储
文章目录
约定
指代图的点数, 指代图的边数, 指代点 的出度。
邻接矩阵
方法
使用二维数组 adj 存边,其中 adj[u][v] 为 1 代表存在从 到 的边,0 表示不存在。如果是带权图,可以存储权重。
复杂度
查询是否存在某条边:
遍历一个点的所有出边:
遍历整张图:
空间复杂度:
应用
邻接矩阵只适用于没有重边(或重边可以忽略)的情况。
优点是可以以 查询边的存在性。
缺点是空间复杂度高,在稀疏图上空间浪费严重。
邻接表
方法
在邻接表的表示中,对于图中的每个顶点,将保存所有其它与之相连的顶点(即“邻接表”)。
在实现上使用一个支持动态增加元素的数据结构构成的数组,如 vector<int> adj[n + 1] 来存边,其中 adj[u] 存储的是点 的所有出边的相关信息(终点,边权)。
复杂度
查询是否存在从 到 的边:
遍历 的所有出边:
遍历整张图:
空间复杂度:
应用
具有通用性,特别是需要对一个点的所有出边进行排序的场合。
链式前向星(Chain Forward Star)
【图论02】动画说图的三种保存方式 降低理解门槛 邻接表 链式前向星 邻接矩阵_哔哩哔哩_bilibili
实现
以边为基本单位,记录每条边的目标点。
链式前向星是一种静态链表存储,用边集数组和邻接表相结合,可以快速访问一个顶点的所有邻接点。
链式前向星存储包括两种结构:
-
头结点数组:head[],head[i]存以i为起点的最后一条边的下标(在edge[]中的下标)。
-
边数组:edge[],edge[i] 表示第 i 条边。
struct node { int to; // 第 i 条边的目标点 int w; // 第 i 条边的边权 int next; // 第 i 条边同起点的下一跳边的位置} edge[maxn]
// head[u]和cnt起始设置为-1int head[maxn] = {-1, ..., -1}; // 头结点数组, 最近一输入的以 i 为起点的边在 edge[] 中的下标int cnt = -1;
void add(int u, int v, int w) { ++cnt;
edge[cnt].to = v; edge[cnt].next = head[u]; edge[cnt].w = w; head[u] = cnt;}复杂度
查询是否存在从 到 的边:
遍历 的所有出边:
遍历整张图:
空间复杂度:
应用
存各种图都很适合,但不能快速查询一条边是否存在,也不能方便地对一个点的出边进行排序。
优点是边都是带编号的。