携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
图的概念
- 定义: 线性表可以是空表,树可以是空树,但图一定非空(边集可以为空)
- 简单图和多重图 简单图:不存在重复的边,不存在到自己的边 多重图:
- 度 顶点的度=入度+出度
- 顶点与顶点的关系
| 名称 | 概念 |
|---|---|
| 路径 | 顶点和相邻顶点序偶构成的边形成的序列 |
| 回路/环 | 408不要求区分,但其实是不一样的 |
| 简单路径 | 路径序列中顶点不重复出现 |
| 简单回路 | 除了第一个和最后一个顶点外,顶点不重复 |
| 路径长度 | 边的个数 |
| 距离 | 路径存在:距离=最短路径 |
| 连通 | 无向图两节点之间有路径 |
| 强连通 | 有向图两节点之间互相有路径 |
| 连通分量 | 无向图的极大连通子图=连通分量 |
| 强连通分量 | 有向图的极大连通子图=强连通分量 |
| 生成树 | 包含全部顶点的极小连通子图 |
| 生成森林 | 非连通图中,连通分量的生成树构成生成森林 |
| 生成子图 | 包含全部顶点的子图 |
| 权 | 边的权值 |
| 连通图指的是无向图强连通图指的是有向图 |
图的存储以及基本操作
图的存储
邻接矩阵
领接表
十字链表(有向图)
邻接多重表(无向图)
图的遍历
BFS(广度优先搜索)
- 思路: 首先访问起始顶点v,然后选取与v邻接的全部顶点w1。。。wn,再一次访问w1。。。wn邻接的全部顶点,依次类推,一层一层向下遍历,直到所有节点被访问过为止(一层一层的访问,这一层访问谁是没关系的)
- 代码实现:(以邻接表为存储结构)
DFS(深度优先遍历算法)
- 思路 首先访问起始节点,然后选一条路走到黑,走不下去以后,折返一个点,再从这个新点,一条路走到黑,如此反复,直到所有点都被访问
- 代码实现
图的应用
最小生成树
Prim算法(普利姆算法)
思路 :由小到大,逐步蚕食,每次并入最小路径,形成新的小团体 适用于边稠密图
Kruskal算法(克鲁斯卡尔算法)
思路:在所有离散的边中选最小的边(但两头已经连通的就不选了呀),一直到所有节点都连通 适用于边稀疏图
最短路径问题
单源最短路径(某一顶点到其余各顶点的最短路径)
- BFS(无权图) 此时的广度优先生成树是以搜索起点为根的高度最小的生成树 缺点:只适合求无权图或者每边权值相等的图
- Dijkstra(带权图,无权图)迪杰特斯拉算法
- 思路:
- 1.初始情况下,每个点到V0都有直达路径亦或是中转路径
- 2.第一波,谁短谁纳入V0,就同流合污,
- 3.纳入以后,你得更新每个点到V0的距离,有的点发现自己路过第一波纳入的那个点到V0,比一开始直达到V0近多了,那就更新一手
- 4.第二波,在上面更新的结果里找到这次哪个点到V0的距离最短,在纳入同流合污,
- 5.然后再更新距离表,如此往复 缺点: 不适合有负的权值图
各顶点间的最短路径
- Floyd(带权图,无权图)弗洛伊德算法 思路: 每次加入一个点,看能否经由这个点让路径变短,矩阵则更新 逐个顶点试探。从所有可能的路径中选出一条长度最短的路径 缺点: 能解决有负权值的图,不能解决有"负权回路"的图
有向无环图(Directed Acyclic Graph DAG)描述表达式
步骤: 把操作数不重复地排成一排 标出所有运算符的生效顺序 按顺序分层加入运算符 逐层检查是否可以合并
拓扑排序
- AOV网(active on vertex network):用顶点表示活动的网
- 拓扑排序:
- 思路:
- 1.从AOV网中选择一个没有前驱(入度为0)的顶点输出
- 2.从网中删除该顶点和所有以他为起点的有向边
- 3.重复1,2的内容直到当前的 AOV网为空或当前的网中不存在无前驱的顶点为止
关键路径
-
AOE网的基本概念 只有在某顶点所代表的事件发生后,该顶点出发的各有向边所代表的活动才能开始 只有在进入某顶点的各有向边所代表的活动都已经结束时,该顶点所代表的事件才能发生 在AOE中只有一个入度为0的点,叫源点,一个出度为0的点,叫汇点
-
操作过程:
-
基本概念 ve()事件发生的最早时间 vl()事件发生的最迟时间 e()活动发生的最早时间 l()活动发生的最迟时间 d()活动时间余量:l()- e() 关键活动的时间余量为0
-
解题步骤:
- 按拓扑排序序列,依次求每个点的ve()事件最早发生的时间: 源点的最早发生时间是0 若某一事件有多条路径,则选择开销最大的一条作为ve()的值 累加求最大的过程,此节点的之前节点也是要求最大开销的
- 按逆拓扑排序序列,依次求各个点的vl()事件最迟发生时间: 汇点的vl和ve是相等的:这个也等于关键路径长度 某一点的vl是取,后一个点的vl减去(所有可能)路径上开销 的 最小值
- 求所有活动的最早发生时间e(): 最早时间等于弧的起点的最早发生时间
- 求所有活动的最晚发生时间l(): 最晚时间等于弧的终点的最晚时间-弧的权值
- d()=l()-e()是活动的时间余量: d为0的活动是关键活动,有关键活动可得关键路径
-