1、2019/4/28,1,第7章 图,本章主题:图的基本概念、图的存储结构和图的常用算法 教学目的: 教学重点:图的各种存储方式及其运算 教学难点:图结构存储方式的选择,几种经典图算法的实现 本章内容:图的基本概念 图的存储结构 图的遍历 最小生成树 最短路径 拓扑排序 关键路径,2019/4/28,2,本章主要介绍图的基本概念、图的存储结构和有关图的一些常用算法。通过本章学习,读者应该:1) 了解图的定义和术语2) 掌握图的各种存储结构3) 掌握图的深度优先搜索和广度优先搜索遍历算法4) 理解最小生成树、最短路径、拓扑排序、关键路径等图的常用算法,本章学习导读,2019/4/28,3,图(Gr
2、aph)是一种较线性表和树更为复杂的非线性结构。是对结点的前趋和后继个数不加限制的数据结构,用来描述元素之间“多对多”的关系。在线性结构中,结点之间的关系是线性关系,除开始结点和 终端结点外,每个结点只有一个直接前趋和直接后继。在树形结构中,结点之间的关系实质上是层次关系,同层上的每个结点可以和下一层的零个或多个结点(即孩子)相关,但只能和上一层的一个结点(即双亲)相关(根结点除外)。在图结构中,对结点(图中常称为顶点)的前趋和后继个数不加限制的,即结点之间的关系是任意的。由此,图的应用极为广泛,特别是近年来的迅速发展,已渗透到诸如语言学、逻辑学、物理、化学、电讯工程、计算机科学以及数学的其它
3、分支中。,2019/4/28,4,7. 1 .1 图的定义 图是由一个顶点集 V 和一个弧集 R构成的数据结构。 Graph = (V, R )V = x | x 某个数据对象 , 是顶点的有穷非空集合;R边的有限集合R = (x, y) | x, y V 无向图 或R = | x, y V & Path (x, y)有向图是顶点之间关系的有穷集合,也叫做边(edge)集合。Path (x, y)表示从 x 到 y 的一条单向通路, 它是有方向的。x弧尾,y弧头。,7.1 图及其基本运算,2019/4/28,5,有向图与无向图 有向图中:边用表示,且x与y是有序的。a. 有向图中的边称为“弧”
4、b. x弧尾或初始点 y弧头或终端点 无向图:边用(x, y) 表示,且顶x与 y是无序的。 完全图在具有n 个顶点的有向图中,最大弧数为 n(n-1) 在具有n 个顶点的无向图中,最大边数为 n(n-1)/2 顶点的度 无向图:与该顶点相关的边的数目 有向图:入度ID(v) :以该顶点为头的弧的数目出度OD(v) :以该顶点为尾头的弧的数目在有向图中, 顶点的度等于该顶点的入度与出度之和。,2019/4/28,6,图7-1 无向图和有向图,2019/4/28,7,在图7-1中,图(a)为无向图,其中G1的顶点集合和边集合分别为: V(G1)=1,2,3,4,5,6,7, E(G1)=(1,2
5、),(l,3),(2,3),(3,4),(3,5),(5,6),(5,7)。图(c)为有向图,其中G3的顶点集合和弧集合分别为 V(G3)=1,2,3,4,5,6, E(G3)=,,2019/4/28,8,7.1.2 图的基本术语 1 顶点的度与顶点v相关的边或弧的数目称作顶点v的度。在有向图中,一个顶点依附的弧头数目,称为该顶点的入度。一个顶点依附的弧尾数目,称为该顶点的出度,某个顶点的入度和出度之和称为该顶点的度。 例如图7-1中,无向图G1中顶点3的度为4,顶点5的度为3。例如在图7-1中,有向图G3中顶点1的出度OD (1)=3,入度ID (1)=1,其度TD (1)=4。,2019/
6、4/28,9,2路径和回路在无向图G中,若存在一个顶点序列Vp ,Vi1,Vi2,Vin,Vq, 使得(Vp,Vi1),(Vi1,Vi2),,(Vin,Vq)均属于E(G),则称顶点Vp到Vq存在一条路径。若一条路径上除起点和终点可以相同外,其余顶点均不相同,则称此路径为简单路径。起点和终点相同的路径称为回路;简单路径组成的回路称为简单回路。 路径长度路径上经过的边的数目称为该路径的路径长度。 非带权图的路径长度是指此路径上边/弧的条数。 带权图的路径长度是指路径上各边/弧的权之和。,2019/4/28,10,2019/4/28,11,3.边和弧 边: 无向图中顶点的偶对,写成(Vx,Vy)或
7、(Vy,Vx)。 弧: 有向图中顶点的偶对,Vx,Vy表示从Vx到Vy。 弧头: 弧的终点 弧尾: 弧的起点,弧 Vx,Vy弧尾Vx 弧头Vy,2019/4/28,12,4子图设有两个图 G(V, E) 和 G(V, E)。若 V V 且 EE, 则称 图G 是 图G 的子图。,2019/4/28,13,2019/4/28,14,5连通性在无向图中, 若从顶点v1到顶点v2有路径, 则称顶点v1与v2是连通的。如果图中任意一对顶点vi和vj(vi,vjV)都是连通的, 则称此图是连通图。非连通图的极大连通子图叫做连通分量。 6 强连通图与强连通分量 在有向图中, 若对于每一对顶点vi和vj,
8、都存在一条从vi到vj和从vj到vi的路径, 则称此图是强连通图。非强连通图的极大强连通子图叫做强连通分量。,2019/4/28,15,7网络 权 某些图的边或弧具有与它相关的数, 称之为权。权可以代表一个顶点到另一个顶点的距离,耗费等。 网络 这种带权连通图一般称为网络。如图7-4所示。,2019/4/28,16,8生成树、生成森林 生成树 一个连通图的生成树是它的极小连通子图,在n个顶点的情形下,有n-1条边。生成树是对连通图而言的是连同图的极小连同子图包含图中的所有顶点有且仅有n-1条边 非连通图的生成树则组成一个生成森林。若图中有n个顶点,m个连通分量,则生成森林中有n-m条边。,20
9、19/4/28,17,9邻接点 顶点: 图中的结点 邻接点: 无向图中,若边(x,y)E, 两顶点之间有条边,则两顶点互 为邻接点。x y ( x ,y ) 有向图中,若弧(x,y)E, 从x到y有一条弧,则y是x的邻接点, 但x不是y的邻接点。x y ,2019/4/28,18,7.1.3 图的基本运算图的基本运算: 见P156,2019/4/28,19,7.2.1 邻接矩阵邻接矩阵(Adjacency Matrix)是表示顶点之间相邻关系的矩阵。设G(V,E)是具有n个顶点的图,则G的邻接矩阵是具有如下性质的n阶方阵。,7.2 图的存储结构,无向图的邻接矩阵是以主对角线对称的,有向图的邻接
10、矩阵可能是不对称的。在有向图中:第 i 行 1 的个数就是顶点 i 的出度,第 j 列 1 的个数就是顶点 j 的入度。在无向图中, 第 i 行 (列) 1 的个数就是顶点i 的度。,2019/4/28,20,图7-6 有向图及其邻接矩阵,图7-5 无向图及其邻接矩阵,2019/4/28,21,对于无向图,(vi,vj)和(vj,vi)表示同一条边,因此,在邻接矩阵中Aij=Aji。无向图的邻接矩阵是(关于主对角线)对称矩阵,可用主对角线以上(或以下)的部分表示。对有向图,弧和表示方向不同的两条弧,Aij和Aji表示不同的弧,所以有向图的邻接矩阵一般不具有对称性。 邻接矩阵表示法适合于以顶点为
11、主的运算。,2019/4/28,22,对于有向图,顶点vi的出度OD (vi)等于邻接矩阵第i行元素之和;顶点vi的入度ID (vi)等于邻接矩阵第i列元素之和,即 :,对于无向图,顶点vi的度等于邻接矩阵第i行的元素之和,即:,OD (vi)=,ID (vi)=,TD(vi)=,对于带权图的邻接矩阵,定义为:,2019/4/28,23,顶点表: 一个记录各个顶点信息的一维数组,邻接矩阵:一个表示各个顶点之间的关系(边或弧)的二维数组。 使用邻接矩阵存储结构,可用一维数组表示图的顶点集合,用二维数组表示图的顶点之间关系(边或弧)的集合,数据类型定义如下: #define MAX_VERTEX_
12、NUM 20 /最大顶点数 typedef int AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM; /邻接矩阵类型 typedef struct VertexType vexsMAX_VERTEX_NUM; /顶点表AdjMatrix arcs; /邻接矩阵int vexnum,arcnum; /图的顶点数和弧数 MGraph;由于一般图的边或弧较少,其邻接矩阵的非零元素较少,属稀疏矩阵,因此会造成一定存储空间的浪费。,2019/4/28,24,7.2.2 邻接表 图的链式存储结构1) 为每个顶点建立一个单链表,2) 第i个单链表中包含顶点Vi的所有邻接顶点。 邻
13、接表是图的一种链式存储结构。类似于树的孩子链表表示法。在邻接表中为图中每个顶点建立一个单链表,用单链表中的一个结点表示依附于该顶点的一条边(或表示以该顶点为弧尾的一条弧),称为边(或弧)结点。,2019/4/28,25,把同一个顶点发出的边链接在同一个边链表中,链表的每一个结点代表一条边,叫做表结点(边结点),邻接点域adjvex保存与该边相关联的另一顶点的顶点下标 , 链域nextarc存放指向同一链表中下一个表结点的指针 ,数据域info存放边的权。边链表的表头指针存放在头结点中。头结点以顺序结构存储,其数据域data存放顶点信息,链域firstarc指向链表中第一个顶点。,2019/4/
14、28,26,带权图的边结点中info保存该边上的权值 。顶点 Vi 的边链表的头结点存放在下标为 i 的顶点数组中。在邻接表的边链表中,各个边结点的链入顺序任意,视边结点输入次序而定。,2019/4/28,27,有向图的邻接表和逆邻接表,在有向图的邻接表中,第 i 个链表中结点的个数是顶点Vi的出度。 在有向图的逆邻接表中,第 i 个链表中结点的个数是顶点Vi 的入度。,2019/4/28,28,图7-7 为图7-6 (a)的的邻接表和逆邻接表,图7-7 有向图的邻接表和逆邻接表,7-6 (a),(b),4,1,3,2,0,2,1,2,3,1,0,1,2,3,(c),1,4,3,2,1,3,0
15、,0,3,2,0,1,2,3,2019/4/28,29,网络 (带权图) 的邻接表,2019/4/28,30,存储表示 typedef struct ArcNodeint adjvex;struct ArcNode *nextarc;int info; ArcNode; /边结点类型 typedef struct VNodeVertexType data;ArcNode *firstarc; VNode,AdjListMAX_VERTEX_NUM; typedef structAdjList vertices; /邻接表int vexnum,arcnum; ALGraph;,2019/4/28
16、,31,7.2.3 十字链表 十字链表 (Orthogonal List)是有向图的另一种链式存储结构。 可看作是将有向图的邻接表和逆邻接表结合的一种链表。 在十字链表中,为每个顶点vi设置一个结点,它包含数据域data和两个链域firstout、firstin,称为顶点结点。数据域data用于存放顶点vi的有关信息;链域firstin指向以顶点vi为弧头的第一个弧结点;链域firstout指向以顶点vi为弧尾的第一个弧结点。 弧结点包括四个域:尾域tailvex、头域headvex,链域hlink和tlink。 hlink指向弧头相同的下一条弧,tlink指向弧尾相同的下一条弧;data顶点
17、信息,firstin以该顶点为头的第一个弧结点,firstout以该结点为尾的第一个弧结点,顶点结点,弧结点,2019/4/28,32,图7-8 十字链表,图7-8为图7-6 (a)有向图的十字链表。,采用十字链表表示有向图,很容易找到以顶点vi为弧尾的弧和以顶点vi为弧头的弧,因此顶点的出度、入度都很容易求得。,2019/4/28,33,十字链表的数据类型定义如下: #define MAXV typedef struct /弧结点 int tailvex,headvex; /弧尾和弧头顶点位置struct ArcNode *hlink,*tlink; /弧头相同和弧尾相同的弧的链域 ArcN
18、ode; typedef struct /顶点结点 VertexType data; /顶点信息ArcNode *firstin,*firstout; /分别指向该顶点的第一条入弧和出弧 VexNode;,2019/4/28,34,7.2.4 邻接多重表邻接多重表是无向图的另一种链式存储结构。在邻接多重表中设置一个边结点表示图中的一条边。边结点包含五个域,结构如下所示:,其中:mark 域 标志域,用于对该边进行标记;ivex 域 存放该边依附的一个顶点vi的位置信息;ilink 域 该链域指向依附于顶点vi的另一条边的边结点;jvex 域 存放该边依附的另一个顶点vj的位置信息;jlink
19、域 该链域指向依附于顶点vj的另一条边的边结点。邻接多重表为每个顶点设置一个结点,其结构如下:,2019/4/28,35,图7-9 邻接多重表,图7-9为图7-5 (a)无向图的邻接多重表。,由邻接多重表可以看出,表示边(vi,vj)的边结点通过链域ilink和jlink链入了顶点vi和顶点vj的两个链表中,实现了用一个边结点表示一个边的目的,克服了在邻接表中用两个边结点表示一个边的缺点。因此邻接多重表是无向图的一种很有效的存储结构。,2019/4/28,36,邻接多重表的结点数据类型定义如下: #define MAXV typedef struct /边结点类型 int mark; /访问标
20、识int ivex,jvex; /该边的两个顶点位置信息struct Enode *ilink,*jlink; /分别指向依附这两个顶点的下一条边 Enode; typedef struct /顶点结点类型 VertexType data; /顶点数据域ENode *firstedge; /指向第一条依附该顶点的边 Vnode;,2019/4/28,37,7.3 图的遍历,和树的遍历相似,若从图中某顶点出发访遍图中每个顶点,且每个顶点仅访问一次,此过程称为图的遍历。 (Traversing Graph)。但是,在图中有回路,从图中某一顶点出发访问图中其它顶点时,可能又会回到出发点,而图中或许还
21、有顶点没有访问到,因此,图的遍历较树的遍历更复杂。图的遍历算法是求解图的连通性问题、拓扑排序和求关键路径等算法的基础。图的遍历顺序有两种:深度优先搜索(DFS)和广度优先搜索(BFS)。对每种搜索顺序,访问各顶点的顺序也不是唯一的。,2019/4/28,38,7.3.1 深度优先搜索(DFS) 1 深度优先搜索思想深度优先搜索遍历类似于树的先序遍历。假定给定图G的初态是所有顶点均未被访问过,在G中任选一个顶点i作为遍历的初始点,则深度优先搜索递归调用包含以下操作: (1)访问搜索到的未被访问的邻接点; (2)将此顶点的visited数组元素值置1; (3)搜索该顶点的未被访问的邻接点,若该邻接
22、点存在,则从此邻接点开始进行同样的访问和搜索。 深度优先搜索DFS可描述为: (1)访问v0顶点; (2)置 visitedv0=1; (3)搜索v0未被访问的邻接点w,若存在邻接点w,则DFS(w)。,2019/4/28,39,遍历过程: DFS 在访问图中某一起始顶点 v 后,由 v 出发,访问它的任一邻接顶点 w1;再从 w1 出发,访问与 w1邻 接但还没有访问过的顶点 w2;然后再从 w2 出发,进行类似的访问, 如此进行下去,直至到达所有的邻接顶点都被访问过的顶点 u 为止。接着,退回一步,退到前一次刚访问过的顶点,看是否还有其它没有被访问的邻接顶点。如果有,则访问此顶点,之后再从
23、此顶点出发,进行与前述类似的访问;如果没有,就再退回一步进行搜索。重复上述过程,直到连通图中所有顶点都被访问过为止。,2019/4/28,40,深度优先搜索的示例,图中可能存在回路,且图的任一顶点都可能与其它顶点相通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点。为了避免重复访问,可设置一个标志顶点是否被访问过的辅助数组 visited ,它的初始状态为 0,在图的遍历过程中,一旦某一个顶点 i 被访问,就立即让 visited i 为 1,防止它被多次访问。,2019/4/28,41,对上图,深度优先搜索遍历的顺序(之一)为:v1 v2v4 v8 v5v6v3v7。,图7-1
24、0 深度优先搜索,2019/4/28,42,深度优先搜索算法:int visitedMAX_VERTEX_NUM;void DFS(ALGraph G, int v) ArcNode *p;printf(“%c“,G.verticesv.data);visitedv=1;p=G.verticesv.firstarc;while (p) if (!visitedp-adjvex) DFS(G,p-adjvex);p=p-nextarc; /从第v个顶点出发DFS,2019/4/28,43,整个图的DFS遍历 void DFSTraverse(ALGraph G)for (int v=0;vG.v
25、exnum;+v)visitedv=0;for (v=0;vG.vexnum;+v)if (!visitedv) DFS(G,v);对于连通图,从一个顶点出发,调用DFS函数即可将所有顶点都遍历到。,2019/4/28,44,7.3.2 广度优先搜索(BFS) 1 广度优先搜索思想广度优先搜索遍历类似于树的按层次遍历。对于无向连通图,广度优先搜索是从图的某个顶点v0出发,在访问v0之后,依次搜索访问v0的各个未被访问过的邻接点w1,w2,。然后顺序搜索访问w1的各未被访问过的邻接点,w2的各未被访问过的邻接点,。即从v0开始,由近至远,按层次依次访问与v0有路径相通且路径长度分别为1,2,的顶
26、点,直至连通图中所有顶点都被访问一次。广度优先搜索的顺序不是唯一的,例如图7-10 (a) 连通图的广度优先搜索遍历顺序可为v1,v2,v3,v4,v5,v6,v7,v8 也可为v1,v3,v2,v7,v6,v5,v4,v8。,2019/4/28,45,1 广度优先搜索思想设图G的初态是所有顶点均未访问,在G 中任选一顶点i作为初始点,则广度优先搜索的基本思想是:(1)从图中的某个顶点V出发,访问之;并将其访问标志置为已被访问,即visitedi=1; (2)依次访问顶点V的各个未被访问过的邻接 点,将V的全部邻接点都访问到; (3)分别从这些邻接点出发,依次访问它们的未被访问过的邻接点,并使
27、“先被访问的顶 点的邻接点”先于“后被访问的顶点的邻接点”被访问,直到图中所有已被访问过的顶 点的邻接点都被访问到。 依此类推,直到图中所有顶点都被访问完为止 。,2019/4/28,46,广度优先搜索在搜索访问一层时,需要记住已被访问的顶点,以便在访问下层顶点时,从已被访问的顶点出发搜索访问其邻接点。所以在广度优先搜索中需要设置一个队列Queue,使已被访问的顶点顺序由队尾进入队列。在搜索访问下层顶点时,先从队首取出一个已被访问的上层顶点,再从该顶点出发搜索访问它的各个邻接点。,广度优先搜索过程 广度优先生成树,广度优先搜索的示例,2019/4/28,47,7.4 最小生成树,1. 生成树在
28、一个无向连通图G中,其所有顶点和遍历该图经过的所有边所构成的子图G 称做图G的生成树。一个图可以有多个生成树,从不同的顶点出发,采用不同的遍历顺序,遍历时所经过的边也就不同,例如图7-12的(b) 和(c) 为图7-12 (a) 的两棵生成树。其中 (b) 是通过DFS得到的,称为深度优先生成树;(c) 是通过BFS得到的,称为广度优先生成树。,图7-12 生成树,2019/4/28,48,按照生成树的定义,n 个顶点的连通网络的生成树有 n 个顶点、n-1 条边。而所有包含n-1 条边及n个顶点的连通图都是无回路的树,所以生成树是连通图中的极小连通子图.由于使用不同的遍历图的方法,可以得到不
29、同的生成树;从不同的顶点出发,也可能得到不同的生成树。如深度优先生成树、广度优先生成树在图论中,常常将树定义为一个无回路连通图。对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树。求图的最小生成树有很多实际应用。例如,通讯线路铺设造价最优问题就是一个最小生成树问题。,2019/4/28,49,假设把n个城市看作图的n个顶点,边表示两个城市之间的线路,每条边上的权值表示铺设该线路所需造价。铺设线路连接n个城市,但不形成回路,这实际上就是图的生成树,而以最少的线路铺设造价连接各个城市,即求线路铺设造价最优问题,实际上就是在图的生成
30、树中选择权值之和最小的生成树。构造最小生成树的算法有很多,下面分别介绍克鲁斯卡尔(Kruskal)算法和普里姆(Prim)算法。,7.4.1 克鲁斯卡尔(Kruskal)算法克鲁斯卡尔算法是一种按权值递增的次序选择合适的边来构造最小生成树的方法。,2019/4/28,50,算法的基本思想: 在图中任取一个顶点K作为开始点,令U=k,W=V-U,其中V为图中所有顶点集,然后找一个顶点在U中,另一个顶点在W中的边中最短的一条,找到后,将该边作为最小生成树的树边保存起来,并将该边顶点全部加入U集合中,并从W中删去这些顶点,然后重新调整U中顶点到W中顶点的距离, 使之保持最小,再重复此过程,直到W为空
31、集止。假设G=(V,E)是一个具有n个顶点的带权无向连通图,T= (U,TE)是G的最小生成树,其中U是T的顶点集,TE是T的边集,则构造最小生成树的过程如下: (1) 置U的初值等于V,TE的初值为空集; (2) 按权值从小到大的顺序依次选取图G中的边,若选取的边未使生成树T形成回路,则加入TE;若选取的边使生成树T形成回路,则将其舍弃。循环执行(2),直到TE中包含(n-1)条边为止。,2019/4/28,51,应用克鲁斯卡尔算法构造最小生成树的过程:,2019/4/28,52,7.5 最短路径,交通网络中常常提出这样的问题:从甲地到乙地之间是否有公路连通? 在有多条通路的情况下,哪一条路
32、最短? 交通网络可用带权图来表示。顶点表示城市名称,边表示两个城市有路连通,边上权值可表示两城市之间的距离、交通费或途中所花费的时间等。求两个顶点之间的最短路径,不是指路径上边数之和最少,而是指路径上各边的权值之和最小。另外,若两个顶点之间没有边,但有可能有间接通路(从其它顶点达到)。路径上的开始顶点(出发点)称为源点,路径上的最后一个顶点称为终点,并假定讨论的权值不能为负数。,2019/4/28,53,最短路径:如果从图中某一顶点(称为源点)到达另一顶点(称为终点)的路径可能不止一条,如何找到一条路径使得沿此路径上各边上的权值总和达到最小。 对于带权的图,通常把一条路径上所经过边或弧上的权值
33、之和定义为该路径的路径长度。从一个顶点到另一个顶点可能存在着多条路径,把路径长度最短的那条路径称为最短路径,其路径长度称为最短路径长度。无权图实际上是有权图的一种特例,我们可以把无权图的每条边或弧的权值看成是l,每条路径上所经过的边或弧数即为路径长度。本章讨论两种最常见的最短路径问题。,2019/4/28,54,问题解法边上权值非负情形的单源最短路径问题 Dijkstra算法 所有顶点之间的最短路径 Floyd算法 边上权值非负情形的单源最短路径问题问题的提法: 给定一个带权有向图D与源点v,求从v到D中其它顶点的最短路径。限定各边上的权值大于或等于0。 为求得这些最短路径,Dijkstra提
34、出按路径长度的递增次序,逐步产生最短路径的算法。首先求出长度最短的一条最短路径,再参照它求出长度次短的一条最短路径,依次类推,直到从顶点v到其它各顶点的最短路径全部求出为止。,2019/4/28,55,7.5.1 求一顶点(单源点)到其余顶点的最短路径 单源点最短路径是指:给定一个出发点(单源点)和一个有向网G=(V,E),求出源点到其它各顶点之间的最短路径。迪杰斯特拉(Dijkstra)在做了大量观察后,首先提出了按路径长度递增产生各顶点的最短路径算法,我们称之为迪杰斯特拉算法。算法的基本思想是:设置并逐步扩充一个集合S,存放已求出其最短路径的顶点,则尚未确定最短路径的顶点集合是V-S,其中
35、V为网中所有顶点集合。按最短路径长度递增的顺序逐个以V-S中的顶点加到S中,直到S中包含全部顶点,而V-S为空。,2019/4/28,56,具体做法是:设源点为Vl,则S中只包含顶点Vl,令W=V-S,则W中包含除Vl外图中所有顶点,Vl对应的距离值为0,W中顶点对应的距离值是这样规定的:若图中有弧则Vj顶点的距离为此弧权值,否则为(一个很大的数),然后每次从W中的顶点中选一个其距离值为最小的顶点Vm加入到S中,每往S中加入一个顶点Vm,就要对W中的各个顶点的距离值进行一次修改。若加进Vm做中间顶点,使+的值小于值,则用+代替原来Vj的距离,修改后再在W中选距离值最小的顶点加入到S中,如此进行
36、下去,直到S中包含了图中所有顶点为止。,2019/4/28,57,从源点 a 到图中其它各终点的最短路径按路径长度从短到长依次为: 路径a, c的长度为8, 路径a, c, f的长度为11, 路径a, c, f, e的长度为13, 路径a, d的长度为15, 路径a, d, g的长度为19, 路径a, d, g, b的长度为22。,2019/4/28,58,(a),(b),(c),(d),2019/4/28,59,图是一种非线性数据结构。本章介绍有关图的基本概念,如顶点和边/弧、无向图和有向图,完全图、网、顶点的度、路径、回路、子图、图的连通性等。图主要具有邻接矩阵、邻接表、十字链表和邻接多重表等存储结构,用以表示图中的顶点信息、边的信息以及顶点与边的关系信息。图的遍历是图的一种重要运算,是从图的某一顶点出发,访遍图中每个顶点,且每个顶点仅访问一次,图的遍历顺序主要有深度优先搜索和广度优先搜索。最后讨论了求最小生成树的两种算法、求解最短路径的两类算法、拓扑排序和关键路径等常用算法。,本章小结,