第六章 图.docx
《第六章 图.docx》由会员分享,可在线阅读,更多相关《第六章 图.docx(12页珍藏版)》请在冰豆网上搜索。
第六章图
第六章图
一、图的定义
图是由顶点的有穷非空集合和顶点之间边的集合组成 G=(V,E)
2、图的基本术语
1.无向图:
图的任意两个顶点之间的边都是无向边
有向图:
图中存在两个顶点之间的边是有向边
2.简单图:
图中不存在顶点到其自身的边,也不存在重复出现的边
3.邻接/依附:
在无向图中,对于任意顶点Vi和Vj,若存在边(Vi,Vj),则称顶点Vi,Vj互为邻接点,边(Vi,Vj)依附于顶点Vi和Vj
在有向图中,对于任意顶点Vi和Vj,若存在弧,则称顶点Vj是Vi的邻接点,弧依附于顶点Vi和Vj
4.无向完全图:
无向图中任意两个顶点之间都存在边
有向完全图:
有向图中任意两个顶点之间都存在方向互为相反的两条弧
含有n个顶点的无向完全图共有n*(n-1)/2条边;含有n个顶点的有向完全图共有n*(n-1)条边
5.顶点的度:
(1)无向图中某顶点的度:
指依附于该顶点的边的个数
(2)有向图中某顶点的入度:
指以该顶点为弧头的弧的个数
有向图中某顶点的出度:
指以该顶点为弧尾的弧的个数
(3)在有n个顶点e条边的无向图中,所有的顶点度数之和=2e
在有n个顶点e条边的有向图中,所有的顶点的入度之和=所有顶点的出度之和=e
6.权/网:
在图中,权通常是指对边赋予的有意义的数值量;边上带权的图称为网或网图
7.路径/路径长度/回路:
(1)图中两个顶点之间的路径:
指这两个顶点之间所有顶点组成的一个顶点序列;顶点不重复出现的路径称为简单路径
(2)路径长度:
指路径上边的数目
(3)回路:
指第一个顶点和最后一个顶点相同的路径;除第一个和最后一个顶点之外,其余顶点不重复出现的回路称为简单回路
8.子图:
指由某图中顶点集合的子集和边集合的子集构成的图;一个图可以有多个子图
9.连通图,连通分量/强连通图,强连通分量
(1)连通图:
指任意两个顶点之间均有路径的无向图
连通分量:
指非连通图的极大连通子图(极大是指包含所有连通的顶点及相关联的边)
(2)强连通图:
指任意两个顶点之间相互有路径的有向图
强连通分量:
指非强连通图的极大强连通子图
10.生成树/生成森林
(1)连通图的生成树:
指只访问每个顶点一次,经过的顶点和边构成的子图,即包含图中所有顶点的一个极小连通子图
(2)有向图的生成树:
是包含图中所有顶点的一个子图,且该子图只有一个入度为0的顶点,其余顶点入度均为1
(3)生成森林:
非连通图的每个连通分量都可以得到一棵生成树,这些生成树构成了非连通图的生成森林
(4)图的生成树可以在遍历过程中得到,具有n个顶点的生成树有且仅有n-1条边
(5)图的生成树是无环图,且可能不唯一;
3、图的遍历
图的遍历:
从图中某一顶点出发,对图中所有顶点访问一次且仅访问一次,实质上是对每个顶点查找其邻接点的过程
1.遍历可从图中任一顶点出发,一般选择从编号较小的顶点开始,所以采用数组存储图的顶点信息,编号从0开始
2.多次重复从某一顶点出发进行图的遍历,这样就可以遍历到图中所有的顶点
3.为了在遍历过程中便于区分顶点是否已被访问,设置一个访问标识变量数组visited[n],初值为0
4.图的遍历次序有两种:
深度优先遍历和广度优先遍历,对无向图和有向图都试用
深度优先遍历是以递归方式进行的,需用栈记载遍历路线,相当于树的前序遍历;
广度优先遍历是以层次方式进行的,需用队列保存已访问的顶点,相当于树的层序遍历;
深度优先遍历和广度优先遍历的遍历结果都可能不唯一;
(1)深度优先:
①选定起始点V0;
②选择一个与V0邻接且未被访问过的顶点V1;
③从V1出发按邻接方向继续访问,当遇到一个顶点所有邻接点均已被访问时,回到该顶点的前一个点,再寻求未被访问过的邻接点,直到所有顶点都被访问过一次;
(2)广度优先:
①选定起始点V0;
②访问与V0邻接的所有顶点V1,V2,……,Vk,这些作为第一层遍历结果;
③在第一层遍历结果中选定一个顶点V1为起点;
④重复②③,直到所有节点都被访问过一次;
4、图的存储结构
图包含的信息:
顶点信息+顶点之间的邻接关系(边或弧)的信息
图没有顺序存储结构,常用存储结构为:
邻接矩阵;邻接表;十字链表;邻接多重表;边集数组
4.1邻接矩阵
1.邻接矩阵:
用一维数组存储顶点信息,二维数组存储顶点之间的邻接关系,这个二维数组称为邻接矩阵,图中若有n个顶点,则邻接矩阵为n*n的方阵arc[n][n]
2.邻接矩阵的求法
(1)无/有向图中:
若Vi邻接到Vj,则arc[i][j]=1,否则arc[i][j]=0;
(2)网图中:
若Vi邻接到Vj,arc[i][j]=权值;若不邻接,arc[i][j]=无限大;若i=j,arc[i][j]=0
3.邻接矩阵的性质
(1)无向图的邻接矩阵一定是对称矩阵,而有向图的邻接矩阵不一定对称
(2)无向图中顶点i的度=第i行非0元素的个数
(3)有向图中顶点i的出度=第i行非0元素的个数
有向图中顶点i的入度=第i列非0元素的个数
4.邻接矩阵遍历图的效率
深度优先和广度优先遍历图的时间复杂度均为O(n^2)
4.2邻接表
1.邻接表:
是一种顺序存储与链接存储相结合的存储方法,包含两种结点结构:
顶点表结点+边表结点
顶点表(表头数组):
存储边表头指针的数组+存储顶点信息的数组
边表(出边表):
对于图的每个顶点Vi,将其所有的邻接点组成的单链表称为顶点Vi的边表(有向图中称为出边表)
入边表:
对于图的每个顶点Vi,将所有以Vi为弧头的弧连接起来,形成入边表,用于建立有向图的逆邻接表
对于网图:
还需在边表结点中间增设一个info域来存储权值
2.邻接表的求法
示例1:
画出无向图的邻接表存储示意图
示例2:
画出有向图的邻接表和逆邻接表存储示意图
3.邻接表的性质
(1)无向图中,顶点i的度=顶点i的边表中的结点个数
(2)有向图中,顶点i的出度=顶点i的出边表中的结点个数;
有向图中,顶点i的入度=各顶点的出边表中以i为终点的结点个数=顶点i的入边表中的结点个数
4.邻接表遍历图的效率
深度优先和广度优先遍历图的时间复杂度均为O(n+e)
4.3十字链表
1.十字链表:
邻接表和逆邻接表的结合,是专用于有向图的一种存储方法
2.十字链表的求法
示例:
画出有向图的十字链表存储示意图
4.4邻接多重表
1.邻接多重表:
和邻接表类似,主要用于存储无向图
2.邻接多重表的求法
示例:
画出无向图的邻接多重表
4.5邻接矩阵与邻接表的比较
1.相同点:
均可用于存储有向图、无向图和网图
2.不同点:
(1)空间性能:
邻接矩阵空间代价为O(n^2);邻接表的空间代价为O(n+e)
(2)时间性能:
邻接矩阵的时间性能为O(n);邻接表的时间性能为O(e/n)
(3)唯一性:
图的邻接矩阵表示是唯一的;但邻接表的表示不唯一
3.对应关系
(1)邻接表中每个顶点的边表对应邻接矩阵的第i行;
(2)邻接表可看做是邻接矩阵带行指针的链接存储
4.选择依据
稠密图一般采用邻接矩阵,稀疏图一般采用邻接表
5、图的重要应用
5.1最小生成数
1.最小生成树:
无向连通网中代价(权值之和)最小的生成树,一定唯一
2.构造最小生成树的三种方法:
(1)克鲁斯卡尔方法(Kruskal)
①将所有权值按从小到大排列;
②先画权值最小的边,然后去掉其边值;重新按小到大排序;
③再画权值最小的边,若最小的边有几条相同的,选择时要满足不能出现回路,然后去掉其边值;重新按小到大排序;
④重复③,直到所有顶点都被访问过一次;
(2)管梅谷算法(破圈法)
①在图中取一回路,去掉回路中最大权值的边得一子图;
②在子图中再取一回路,去掉回路中最大权值的边再得一子图;
③重复②,直到所有顶点都被访问过一次;
(3)普利姆算法(Prim)
①在图中任取一点为起点V1,连接边值最小的邻接点V2;
②以邻接点V2为起点,找到V2邻接的最小边值,如果该最小边值比V1邻接的所有边值都小(除已连接的边值),直接连接,否则退回V1,连接V1现在的最小边值(除已连接的边值);
③重复操作,直到所有顶点都被访问过一次;
3.Prim算法和Kruskal算法的比较
(1)Prim算法的时间复杂度为O(n^2);适应于求稠密网的最小生成树
(2)Kruskal算法的时间复杂度为O(elog2e);适应于求稀疏网的最小生成树
5.2最短路径
1.最短路径:
在非网图中指两点之间经历边数最少的路径;在网图中指两点之间经历权值之和最小的路径
2.源点/终点:
源点-路径上的第一个顶点;终点-路径上的最后一个顶点
3.求最短路径的两种方法:
Dijkstra算法;Floyd算法
4.Dijkstra算法
(1)原理:
按路径长度递增的次序产生单源点最短路径
(2)基本思想:
用集合S存放已求最短路径的顶点,初始只有源点V0,当求出源点到集合V-S中的顶点Vk的最短路径时,将Vk移入集合S中
(3)最短路径求法
第一步:
画出网图的邻接矩阵
第二步:
画出以下表格格式,并求出每个方格的d[i]/p[i]
第三步:
写出结果,即求得源点到各顶点的最短路径
(4)示例:
如图所示,用Dijkstra算法求从顶点V1到其他各顶点的最短路径
5.Dijkstra算法和Floyd算法的比较
Dijkstra算法按路径长度递增的次序产生单源点最短路径,时间复杂度为O(n^2);
Floyd算法采用迭代的方式求得每一对顶点之间的最短路径,时间复杂度为O(n^3)
5.3拓扑排序
1.AOV网:
是用顶点表示活动,弧表示活动之间的优先关系的有向图
2.拓扑排序
(1)拓扑序列:
若从顶点Vi到Vj有一条路径,则在顶点序列中Vi必在Vj之前
(2)拓扑排序:
对一个有向图构造拓扑序列的过程
(3)对AOV网进行拓扑排序的方法:
第一步:
AOV网中选择一个入度为0的顶点,输出它,然后删除该顶点及它所有的出边
第二步:
重复第一步,直到所有顶点都被输出或AOV网中不存在入度为0的顶点
(4)判定AOV网是否有回路的方法
对AOV网进行拓扑排序,若所有顶点都被输出,则不存在回路;否则存在回路
3.拓扑排序的应用
测试AOV网所代表的工程能否顺利进行的方法是判断AOV网是否有回路;判断AOV网是否有回路的方法是对AOV网进行拓扑排序;
所以任何一个工程的各个活动安排必须按拓扑序列中的顺序进行才是可行的,并且一个AOV网的拓扑序列可能不唯一
5.4关键路径
1.AOE网:
是用顶点表示事件,有向边表示活动,边上权值表示活动持续时间的有向图
源点:
AOE网中入度为0的顶点
终点:
AOE网中出度为0的顶点
2.AOE网的性质
①只有某顶点代表的事件发生后,该事件后的各个活动才能开始
②只有某事件之前的所有活动都已结束,该顶点代表的事件才能发生
3.关键路径
(1)路径长度:
某路径上各个活动所持续的时间之和
(2)关键路径:
从源点到终点最大路径长度的路径,关键路径可能不唯一,但长度唯一
(3)关键活动:
关键路径上的活动
(4)最短工期:
关键路径的路径长度
4.关键路径的求法
第一步:
(1)计算事件的最早发生时间ve[k],k为顶点,从源点开始计算;
①ve[源点]=0
②ve[其他事件]=max{ve[前驱事件]+该前驱顶点到k之间的活动时间}
(2)计算事件的最晚发生时间vl[k],k为顶点,从终点开始计算;
①vl[终点]=ve[终点]
②vl[其它事件]=min{vl[后继事件]-该后继顶点到k之间的活动时间}
第二步:
(1)计算活动的最早开始时间e[k],k为边,从源点开始计算;
e[k]=ve[k所在边的起点]
(2)计算活动的最晚开始时间l[k],k为边,从源点开始计算;
l[k]=vl[k所在边的终点]-k所在边的活动时间
(3)计算活动的缓冲时间t[k]:
活动的最晚开始时间减去最早开始时间
t[k]=l[k]-e[k]
第三步:
得出结果:
缓冲时间为0的活动为关键活动,关键活动所在的路径为关键路径
5.示例:
求有向网的关键路径
6、知识点拓展
1.图可以没有边,但必须要有顶点,图至少有0条边,至多达到完全图的数量;
2.连通图的连通分量是其本身;连通分量可能存在回路;完全图一定是连通图;
3.n个顶点的连通图中任意简单路径的长度不大于n-1;
4.n个顶点的强连通图至少有n条边,形状是一个环状;
5.生成树是无环图;生成树可能不唯一;但最小生成树一定唯一;
6.只有连通图从某顶点出发进行一次遍历,可访问图中所有顶点;
7.深度优先遍历时若按退栈次序打印顶点,则输出的是逆拓扑序列;
8.深度优先遍历和广度优先遍历的遍历结果可能不唯一;
9.邻接矩阵的存储空间只与图中顶点个数有关,与边数无关;
10.邻接矩阵存储无向图时,图中的边数=邻接矩阵中非0元素个数总和/2;
11.邻接矩阵存储有向图时,图中的边数=邻接矩阵中非0元素个数总和;
12.邻接表存储无向图时,图中的边数=边表中结点个数之和/2;
13.邻接表存储有向图时,图中的边数=边表中结点个数之和;
14.邻接表存储有向图时,图中邻接表的结点个数之和=逆邻接表的结点个数之和=n+e;
15.图的邻接矩阵表示一定唯一,邻接表和其他存储表示不唯一;
16.Prim算法-顶点出发,邻接最小;Kruskal算法-排序权值,连接最小;
17.若一个有向图的邻接矩阵对角线以下元素都为0,则该图的拓扑排序必定存在;
18.拓扑排序序列可能不唯一;
19.关键路径可能不唯一,但关键路径长度一定唯一;
20.同时提高几条关键路径上的关键活动才能提前整个工程;