前言
数据结构中 图的重要性不言而喻了,在此进行学习记录。
参考文章:
- 《数据结构与算法Python语言》 这本书
1. 图的基本概念
1.1 图的定义
G= <V,E>
图是由顶点和边组成
图的分类:
- 有向图
边是有方向,是顶点的有序对
出度:由它指向别的顶点的个数
入度:别的顶点指向它的个数 - 无向图
边是没有方向,是顶点的无序对
度:顶点连接其他顶点的边的个数
1.2 图的一些概念和性质
-
完全图:任意两个顶点之间都有边的图(有向图或无向图)
-
路径:顶点到另一个顶点经过的边
-
回路(环路)起点和终点相同的路径
简单回路:一个环路除起点和终点外其他顶点均不相同 -
有根图:有向图中存在一个顶点到其他顶点均有路径
连通图
- 连通:存在顶点到顶点的路径
- 连通无向图:无向图中任意两个顶点之间都连通
- 强连通有向图:有向图,任意两个顶点都连通
- 最小连通图:去掉任意一条边,都不是连通图
完全无向图都是连通图,完全有向图都是强连通有向图;反之不对。
子图、连通子图
- 子图:就是原图的一部分
- 连通子图:子图是连通的,称为原图的连通子图
带权图和网络
- 带权图: 每条边都被赋予一个权值
- 网络:带权的连通无向图
图抽象数据类型
- 图看作是一种数据结构
- 定义一个图抽象数据类型的操作
图的表示
- 邻接矩阵
无向图:
有向图:
邻接矩阵表示法的缺点:空间浪费比较大
为了降低图表示的空间代价,可看作邻接矩阵的压缩版,方法有:
-
邻接表表示法
-
邻接多重表表示法
-
图的十字链表表示法
-
邻接表
为图中每个顶点关联一个边表,记录这个顶点的所有邻接边
具体Python实现暂不进行讨论。
2. 基本图算法
2.1 图的遍历
- 深度优先遍历(DFS):深度优先搜索
- 广度优先遍历(BFS):广度优先搜索
2.2 生成树
生成树:原图,N个顶点和N-1 边的子图,最小连通子图,生成树
遍历:DFS、BFS
最小生成树:带权图,权值最小的生成树成为最小生成树
解法:
- Kruskal 算法
权值排序,从小往大选取,相同权值选择其中一个
n顶点,n-1 边
最小生成树不唯一
- Prim算法
从一个顶点出发,选择最小权重,逐步扩充包含该顶点的部分生成树
2. 3 最短路径
定义:
- 路径长度: 顶点到顶点的一个路径上各边长度之和
- 最短路径长度:路径长度中最短的
- 实际应用:运输(最短里程、最短运费、最低成本、最少时间);加工或者工作流程
算法:
- Dijkstra 算法
一个给定顶点到其他顶点的最短路径
要求图中所有边的权值不小于0
- Floyd 算法
直接求出所有顶点之间的最短路径及其长度
2.4 AOV/AOE 网及其算法
- AOV : 有向图中的边表示各项活动之间的先后顺序,成为顶点活动网或AOV
可以把AOV网络里的有向边看作一种“顺序”关系。拓扑排序问题就是问,在一个AOV网里的活动能否排成一种全序。
一个AOV 网有拓扑序列,其拓扑序列未必唯一
拓扑排序算法:
选择入度为0 的顶点作为序列的下一个顶点;删除所选顶点及其所有的出边;重复操作;找不到入度为0 的顶点。
拓扑排序的序列有多种。
- AOE:无环的带权有向图,顶点表示事件,边表示活动,权值表示活动持续的时间
关键路径:完成整个工程的最短时间,就是从开始顶点到完成顶点的最长路径的长度(即,路径上各条边的权值之和),这种最长路径成为AOE网 的关键路径
关键路径算法:
事件最早可能发生的时间(前向推),多个指向,选择最大的;事件最晚发生的时间(反向推出),多个指向,选择最小的