1354 字
7 分钟
图
2024-09-15
无标签
概念
- 有向图 无向图
- 带权图
- 简单图 多重图
- 子图
- 完全图
- 连通图 连通分量 强连通分量 弱连通分量 极大连通子图
- 生成树 生成森林 极小连通子图
- 树
- 度
- 对无向图 度之和为边数乘2
- 对无向图 入度等于初度等于边数,总度等于入度与出度之和
- 路径 两个顶点之间的顶点序列
- 回路 简单回路
- 路径长度:路径上边的数量
- 距离 最短路径
- 对于简单无向图
- 当 一定是非连通的
- 当 一定是连通的 有一个节点是一个孤岛,其余节点构成完全图,有一个桥连接两个岛屿
- 当 介于两者之间可能是…也可能是…
- 对于简单有向图
- 当 一定是非强连通的
- 当 一定是强连通的 有一个节点是一个孤岛,其余节点构成完全图,有一个桥连接两个岛屿
- 当 介于两者之间可能是…也可能是…
- 当简单 有向图/无向图 边数/顶点数固定 (强)连通/非(强)连通 顶点数/边数 至多/至少为,一共16种情况思考每种情况的答案是多少
物理存储结构
| 空间复杂度 | 特点 | 度 | 适用情况 | 其他 | |
|---|---|---|---|---|---|
| 邻接矩阵 | 查询两个点的邻接关系方便,遍历一个顶点的出边或者入边要遍历对应的行或列 | 对于无向图即对应行或列的元素之和,对于有向图出度是对应行之和入度是对应列之和 | 边稠密 | 无向图是对称矩阵且对角线元素为0可以压缩存储,01邻接矩阵的n次幂表示从i到j顶点的长度为n的路径的数量 | |
| 邻接表(有向图) | 有向图无向图 | 查询两个点的邻接关系麻烦,遍历一个顶点的所有边比较方便,对于无向图一条边要存储两次,对于有向图不能遍历入边 | 对于无向图即邻接表的长度,对于有向图只能获得出度 | 边稀疏 | |
| 十字链表 | 查询两个点的邻接关系麻烦,遍历一个顶点的所有出入边比较方便 | 出度为邻接出边表,入度为邻接出边表的长度 | 边稀疏 | ||
| 多重邻接表 | 查询两个点的邻接关系麻烦,遍历一个顶点的所有边比较方便 | 邻接表长度 | 边稀疏 |
遍历
BFS
- 时间复杂度 遍历所有节点的所有边所以对于邻接矩阵而言复杂度是,对于邻接表是
DFS
- 同上
BFS/DFS 生成树/森林
(带权图)最小生成树
BFS/DFS
仅适用于非带权图
prim
- 每次将代价最小的顶点接入树
- 适合边稠密的情况
kruskal
- 每次选择权值最小的边,连接两个连通分量
- 适合边稀疏的图
- 采用堆存放边的集合选出最小的边
- 复杂度
- 每次选择边
- 最坏需要轮,复杂度
最短路径
bfs
仅适用于无权图
dijk
final[]标记对应节点是否已经找到最短路径dist[]计算出的最短路径长度path[]计算出的最短路径的前驱- 不适合求有负权值的图
- 类比#prim
- 时间复杂度
floyd
- 不能有负的回路
- 复杂度
DAG
描述表达式
拓扑排序
使用dfs实现
dfs(node) {
for neigh in node.neighbours.filter(_ => !_.has_visited) {
dfs(neigh)
}
print(node)
}
输出序列是一个逆拓扑排序,对其反转后得到拓扑排序
经典实现
- 从AOV网中找一个入度为0的顶点并输出
- 从AOV网中删除这个顶点和所有以它为起点的边
- 重复直到AOV网为空或者不存在入度为0的点为止
- 遍历所有节点的所有边所以对于邻接矩阵而言复杂度是,对于邻接表是
//假定采用邻接矩阵实现
topological_sort(g) => Maybe<int[]> {
s := []
indegree = g.vexs.map(_ => _.indegree)
res := []
for (i, _) in indegree.enum().filter((_, indegree) => indegree === 0) {
s.push(i)
}
while Some(i) = s.pop() {
res.push(i)
for neigh in g.vex[i] {
indegree[neigh]--
if indegree[neigh] === 0 { s.push(neigh) }
}
}
if res.len === g.vex_num {
return Just(res)
} else {
return Nothing
}
}
关键路径
- AOE网,边是活动,顶点是里程碑
- 事件的最早开始时间 事件的最晚开始时间
- 活动的最早开始时间 弧的起点的事件的最早开始时间
- 活动最晚开始时间 弧的终点的事件的最晚开始时间减去活动的长度
- 活动的余量 活动最晚开始时间与最早开始时间之差
- 遍历所有节点的所有边所以对于邻接矩阵而言复杂度是,对于邻接表是
其他
- 上三角的邻接矩阵必定是有向无环图
- 有向无环图不一定是上三角阵
flowchart LR
1 --> 3 --> 2
- 拓扑序列唯一得不到唯一的有向无环图 如123对应下面两种可能
flowchart LR
1 --> 2 --> 3
flowchart LR
1 --> 2 --> 3
1 --> 3
