图的存储
1、边列表🧀
Danger
查找操作时间复杂度:\(O(E)=O(n^2)\),复杂度太高
2、邻接矩阵🧀
使用一个二维数组 adj
来存边:
- 若
adj[u][v] == 1
,表示存在从u
到v
的边; - 若
adj[u][v] == 0
,表示不存在从u
到v
的边。
对于带边权的图,可以在 adj[u][v]
中存储从 u
到 v
的边的边权。
Tip
无向图:邻接矩阵对称,度就是第几行 \(1\) 的个数
有向图:邻接矩阵不一定对称,缺点是 空间浪费 ;行代表出度,列代表入度
二维数组:graph[NUM][NUM]
无向图:graph[i][j]=graph[j][i]
有向图:graph[i][j]!=graph[j][i]
graph[i][j]=INF
表示i
,j
无边。
Bug
储存效率低下,只适用于稠密图。邻接矩阵只适用于没有重边(或重边可以忽略)的情况。
复杂度🧀
- 查询是否存在某条边:\(O(1)\)
- 遍历一个点的所有出边:\(O(n)\)
- 遍历整张图:\(O(n^2)\)
- 空间复杂度:\(O(n^2)\)
3、邻接表🧀
- 类似于孩子链表表示法
复杂度(邻接表)🧀
- 查询是否存在从 \(u\) 到 \(v\) 的边:\(O(d^+(u))\)
- 如果对邻接表进行排序,则可以使用二分查找,复杂度为 \(O(\log d^+(u))\)
- 遍历点 \(u\) 的所有出边:\(O(d^+(u))\)
- 遍历整张图:\(O(n + m)\)
- 空间复杂度:\(O(m)\)
Note
\(d^+(u)\) 表示点 \(u\) 的出度(即从 \(u\) 出发的边的数量);
\(n\) 表示点数,\(m\) 表示边数;
邻接表默认不存储所有 \(n\) 个点的空表时,也可以视为 \(O(n + m)\) 空间。