转载自 https://blog.csdn.net/xiazdong/article/details/7354411 和
https://blog.csdn.net/LJFYYJ/article/details/80293263。
一、基本术语
图:由有穷、非空点集和边集合组成,简写成G(V,E);
Vertex:图中的顶点;
无向图:图中每条边都没有方向;
有向图:图中每条边都有方向;
无向边:边是没有方向的,写为(a,b)
有向边:边是有方向的,写为<a,b>
有向边也成为弧;开始顶点称为弧尾,结束顶点称为弧头;
简单图:不存在指向自己的边、不存在两条重复的边的图;
无向完全图:每个顶点之间都有一条边的无向图;
有向完全图:每个顶点之间都有两条互为相反的边的无向图;
稀疏图:边相对于顶点来说很少的图;
稠密图:边很多的图;
权重:图中的边可能会带有一个权重,为了区分边的长短;
网:带有权重的图;
度:与特定顶点相连接的边数;
出度、入度:对于有向图的概念,出度表示此顶点为起点的边的数目,入度表示此顶点为终点的边的数目;
环:第一个顶点和最后一个顶点相同的路径;
简单环:除去第一个顶点和最后一个顶点后没有重复顶点的环;
连通图:任意两个顶点都相互连通的图;
极大连通子图:包含竟可能多的顶点(必须是连通的),即找不到另外一个顶点,使得此顶点能够连接到此极大连通子图的任意一个顶点;
连通分量:极大连通子图的数量;
强连通图:此为有向图的概念,表示任意两个顶点a,b,使得a能够连接到b,b也能连接到a 的图;
生成树:n个顶点,n-1条边,并且保证n个顶点相互连通(不存在环);
最小生成树:此生成树的边的权重之和是所有生成树中最小的;
AOV网:结点表示活动的网;
AOE网:边表示活动的持续时间的网;
二、图的存储结构
1.邻接矩阵
维持一个二维数组,arr[i][j]表示i到j的边,如果两顶点之间存在边,则为1,否则为0;
维持一个一维数组,存储顶点信息,比如顶点的名字;
下图为一般的有向图:
注意:如果我们要看vi节点邻接的点,则只需要遍历arr[i]即可;
下图为带有权重的图的邻接矩阵表示法:
缺点:邻接矩阵表示法对于稀疏图来说不合理,因为太浪费空间;
2.邻接表
如果图示一般的图,则如下图:
如果是网,即边带有权值,则如下图:
三、图的遍历
深度优先遍历(Depth First Search)
从图的某顶点v出发,进行深度优先遍历:
由于没有规定访问邻接点的顺序,所以深度优先序列不唯一。
例子:
广度优先遍历(Depth First Search)
从图中某顶点v出发:
深度优先遍历是回溯算法,广度优先遍历时一种分层的顺序搜索过程,不是递归。
四、最小生成树
1、最小生成树的概念
包含无向连通图G所有n个顶点的极小连通子图称为G的生成树。
生成树的特点:T是G的连通子图;T包含G的所有顶点;T中无回路;T中有n-1条边。
权之和最小的生成树为最小生成树。
MST(Minimum Spanning Tree)性质: 若U集是V的一个非空子集,若(U0, V0)是一条权值最小的边,其中U0∈U,V0∈V−U,则:(U0, V0)必在最小生成树上。
2、Prim算法:将顶点归并,与边数无关,适合稠密网O(n^2)
设G=(V,GE)为一个具有n个顶点的连通网络,T=(U,TE)为构造的生成树。
- 初始时,U={u0},TE为空集
- 在所有的u∈U且v∈V−U的边(u,v)中选择一条权值最小的边(u,v)
- 将(u,v)加入TE,同时将v加入U
- 重复23步,直到U=V为止
3、Kruskal算法:将边归并,适用于求稀疏网的最小生成树,O(eloge)
- 初始时最小生成树值包含图的n个顶点,每个顶点为一棵子树
- 选取权值较小且所关联的两个顶点不再同一连通分量的边,将此边加入最小生成树中
- 重复第二步n-1次,即得到包含n个顶点和n-1个条边的最小生成树
五 、有向无环图及其应用
对于有向图中没有限定次序关系的顶点,则可以人为加上任意的次序关系,由此所得顶点的线型序列被称之为拓扑有序序列。
AOV网(Activity On Vertex network)是以顶点表示活动,弧表示活动之间的先后关系的有向图。AOV网中不允许有回路,不允许某项活动以自己为先决条件。
检测AOV网是否存在环:对有向图构造顶点的拓扑有序序列,若图中所有顶点都在该序列中,则AOV网必定不存在环。
AOE网(Activity On Edge)用边表示活动的网。它是一个带权的有向无环图。
AOE网中重要概念:
- 顶点表示时间,弧表示活动
- 权值:活动持续的时间
- 路径长度:路径上各活动的持续时间之和
- 关键路径:路径长度最长的路径叫作关键路径
- 关键活动:该弧上的权值增加将使有向图上的最长路径的长度增加
AOE网和AOV网的区别:
- 一个用顶点表示活动,一个用边表示活动
- AOV网侧重表示活动的前后次序,AOE网除了表示活动的前后次序,还表示了活动的持续时间等。
AOV网或AOE网构造拓扑序列的方法:
- 在有向图中选一个没有前驱(入度为0)的顶点并输出它。
- 从图中删除该顶点和所有以它为尾的弧。(弧头顶点的入度减一)
- 重复上述两步,直至全部顶点均已输出。
数据结构:
- 邻接表存储图
- 数组记录顶点当前的入度
- 栈记录入度为0的点
六、最短路径
1、Dijkstra算法求单源最短路径
方法:S = v0,其余顶点T = 其余顶点u
- 从T中选择一个未标记的权值最小的顶点w,将w加入S,并对w进行标记。若所有点都被标记,则结束。
- 考察T中的所有顶点,对路径进行松弛
无向图和有向图都适用,弧的权值必须非负。
2、Floyd算法求每对顶点间最短路径
当然也可以重复执行Dijkstra算法n次。
弗洛伊德算法:从vi到vj所有可能存在的路径中,选出一条长度最短的路径。所有可能存在的路径中,选出一条长度最短的路径。
方法:
- 初始设置一个n阶方阵,令其对角线元素为0,若存在弧 (vi, vj),则对应元素为权值,否则为无穷。
- 逐步试着在原直接路径中增加中间顶点,若加入中间点后路径变短,则修改。否则,维持原值。
- 所有顶点试探完毕,算法结束。