分享
分享赚钱 收藏 举报 版权申诉 / 136

类型数据结构课件7.ppt

  • 上传人:j35w19
  • 文档编号:6844010
  • 上传时间:2019-04-23
  • 格式:PPT
  • 页数:136
  • 大小:1.88MB
  • 配套讲稿:

    如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。

    特殊限制:

    部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。

    关 键  词:
    数据结构课件7.ppt
    资源描述:

    1、第七章 图,图(Graph)是一种较线性表和树更为复杂的非线性结构。在线性结构中,结点之间的关系是线性关系,除开始结点和终端结点外,每个结点只有一个直接前趋和直接后继。在树形结构中,结点之间的关系实质上是层次关系,同层上的每个结点可以和下一层的零个或多个结点(即孩子)相关,但只能和上一层的一个结点(即双亲)相关(根结点除外)。然而在图结构中,对结点(图中常称为顶点)的前趋和后继个数都是不加限制的,即结点之间的关系是任意的。图中任意两个结点之间都可能相关。由此,图的应用极为广泛,特别是近年来的迅速发展,已渗透到诸如语言学、逻辑学、物理、化学、电讯工程、计算机科学以及数学的其它分支中。,7.1 图

    2、的定义和术语 图(Graph)图G是由两个集合V(G)和E(G)组成的,记为G=(V,E) 其中:V(G)是顶点的非空有限集E(G)是边的有限集合,边是顶点的无序对或有序对 有向图有向图G是由两个集合V(G)和E(G)组成的其中:V(G)是顶点的非空有限集E(G)是有向边(也称弧)的有限集合,弧是顶点的有序对,记为,v,w是顶点,v为弧尾,w为弧头,V(G1)= 1, 2, 3, 4, 5, 6 E(G1)=, , , , , , ,无向图无向图G是由两个集合V(G)和E(G)组成的其中:V(G)是顶点的非空有限集E(G)是边的有限集合,边是顶点的无序对,记为(v,w)或(w,v),并且(v,

    3、w)=(w,v),V(G2)= 1, 2, 3, 4, 5, 6, 7 E(G1)=(1,2), (1,3), (2,3), (2,4),(2,5), (5,6), (5,7),有向完备图n个顶点的有向图最大边数是n(n-1) 无向完备图n个顶点的无向图最大边数是n(n-1)/2 权与图的边或弧相关的数叫 网带权的图叫 子图如果图G(V, E)和图G(V,E),满足:V V E E则称G为G的子图 顶点的度 无向图中,顶点的度为与每个顶点相连的边数 有向图中,顶点的度分成入度与出度 入度:以该顶点为头的弧的数目 出度:以该顶点为尾的弧的数目 路径路径是顶点的序列V=Vi0,Vi1,Vin,满足

    4、(Vij-1,Vij)E 或 E,(1jn),路径长度沿路径边的数目或沿路径各边权值之和 回路第一个顶点和最后一个顶点相同的路径叫 简单路径序列中顶点不重复出现的路径叫 简单回路除了第一个顶点和最后一个顶点外,其余顶点不重复出现的回路叫 连通从顶点V到顶点W有一条路径,则说V和W是 连通图图中任意两个顶点都是连通的叫 连通分量非连通图的每一个连通部分叫 强连通图有向图中,如果对每一对Vi,VjV, ViVj,从Vi到Vj 和从Vj到 Vi都存在路径,则称G是,路径:1,2,3,5,6,3 路径长度:5 简单路径:1,2,3,5 回路:1,2,3,5,6,3,1 简单回路:3,5,6,3,路径:

    5、1,2,5,7,6,5,2,3 路径长度:7 简单路径:1,2,5,7,6 回路:1,2,5,7,6,5,2,1 简单回路:1,2,3,1,连通图,强连通图,非连通图 连通分量,若将图的每条边都赋上一个权,则称这种带权图为网络(Network)。通常权是具有某种意义的数,它们可以表示两个顶点之间的距离,耗费等。,图的存储表示分析 特点:顶点之间的关系是多对多(m : n) m 和 n 都是不定的,无法进行非线性结构的线性化 图中的关系不能通过顺序映像(即通过顶点之间的存储位置反映顶点之间的逻辑关系)反映;必须另外引入存储空间反映顶点之间的邻接关系。 图的存储信息 顶点信息、边/弧信息、整体信息

    6、:顶点数、边/弧数、图的种类(有向图/有向网/无向图/无向网) 顶点集:顺序表存储,不是顺序映像! 关系集:邻接矩阵、邻接表、多重邻接表、十字链表,7.2 存储结构,(1)图的邻接矩阵表示法,邻接矩阵表示顶点间相联关系的矩阵 定义:设G=(V,E)是有n1个顶点的图,G的邻接矩阵A是具有以下性质的n阶方阵,图:邻接关系用1/0表示 网:邻接关系需要进一步反映权值,用INFINITY表示无穷大,反映顶点之间无邻接关系 #define INT_MAX 32767 /* 最大整数 */ #define INFINITY INT_MAX,1) 邻接矩阵 typedef struct ArcCell i

    7、nt adj; / 顶点间关系,无权图:0-不相邻,1-相邻/ 有权图,权值,INFINITY-不相邻 InfoType *info; / 该弧相关信息的指针 ArcCell, AdjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;,2) 图的整体结构 typedef struct VertexType vexsMAX_VERTEX_NUM; /* 有效的顶点下标从0开始 */AdjMatrix arcs; /* 关系集 */int vexnum, arcnum; /* 顶点数、边/弧数 */GraphKind kind; /* 图的种类 */ MGraph;,V1,V3

    8、,V2,V4,V1 V2 V3 V4V1 0 0 1 0V2 0 0 0 1V3 0 0 0 1V4 1 0 0 0,V1 V2 V3 V4V1 0 1 1 1V2 1 0 0 1V3 1 0 0 0V4 1 1 0 0,图的连接矩阵表示法,特点: 无向图的邻接矩阵对称,可压缩存储;有n个顶点的无向图需存储空间为n(n+1)/2 有向图邻接矩阵不一定对称;有n个顶点的有向图需存储空间为n 无向图中顶点Vi的度TD(Vi)是邻接矩阵A中第i行元素之和 有向图中, 顶点Vi的出度是A中第i行元素之和 顶点Vi的入度是A中第i列元素之和 网络的邻接矩阵可定义为:,V1 V2 V3 V4V1 0 0

    9、1 0V2 0 0 0 1V3 0 0 0 1V4 1 0 0 0,V1 V2 V3 V4V1 0 1 1 1V2 1 0 0 1V3 1 0 0 0V4 1 1 0 0,入度 出度,1 1,1 1,2 1,0 1,度数,3,2,1,2,(2)图的邻接表示法即对图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于该顶点Vi的边(或弧)。,图的整体结构 typedef struct AdjList vertices;int vexnum, arcnum;GraphKind kind; ALGraph;,特点 无向图中顶点Vi的度为第i个单链表中的结点数 有向图中 顶点Vi的出度为第i个单链

    10、表中的结点个数 顶点Vi的入度为整个单链表中邻接点域值是i的结点个数 逆邻接表:有向图中对每个结点建立以Vi为头的弧的单链表,7.3 图的遍历和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条搜索路径对图中所有顶点各作一次访问。若给定的图是连通图,则从图中任一顶点出发顺着边可以访问到该图的所有顶点。然而,图的遍历比树的遍历复杂得多,这是因为图中的任一顶点都可能和其余顶点相邻接,故在访问了某个顶点之后,可能顺着某条回路又回到了该顶点。为了避免重复访问同一个顶点,必须记住每个顶点是否被访问过。,1、深度优先遍历(DFS) 方法:从图的某一顶点V0出发,访问此顶点;然后依次从V0的未被访问的邻接点

    11、出发,深度优先遍历图,直至图中所有和V0相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止。,深度遍历:V1 V2 V4 V8 V5 V3 V6 V7,深度遍历:V1 V2 V4 V8 V5 V6 V3 V7,深度遍历:V1 V2 V4 V8 V5 V6 V3 V7,深度遍历:V1 V2 V4 V8 V3 V6 V7 V5,深度优先遍历算法 递归算法,Firstadj(G,v)返回图G中顶点v的第一个邻接点的编号,若不存在,则返回0; Nextadj(G,v,w)返回图G中顶点v的邻接点中处于w之后的那个邻接点的编号

    12、,若不存在,则返回0;约定:搜索邻接点将按从小到大的次序进行。,void traver(TD g) int i;static int visitedM;for(i=1;i=n;i+)visitedi= FALSE; / 访问标志数组初始化for(i=1;i=n;i+)if(!visitedi)dfs(i); ,void dfs(int v0)/ 从顶点v0出发,深度优先搜索遍历连通图 G printf(“%d ”, v0); visitedv0=true; /访问顶点v0w=firstadjG, v0; /返回v0的第一个邻接点while(w!=0)if(!visitedw) dfs(w);/

    13、从v0的邻接点出发做深度遍历w=nextadj(G, v0, w); /取下一个邻接点 ,深度遍历:V1,V3 ,V7 ,V6 ,V2 ,V5 ,V8 ,V4,深度遍历:V1,V3 ,V7 ,V6 ,V2 ,V4 ,V8 ,V5,基于某种存储结构的DFS算法根据选择的存储结构,决定 FirstAdjVex()和NextAdjVex()的实现,重新整合算法。如采用邻接矩阵表示法表示的图,则DFS算法如下:void DFS (MGraph G, int v, Status ( *Visit ) (MGraph G, int v) visitedv = TRUE; Visit(G, v); for

    14、( w = 0; w G.vexnum; w +) if ( G.arcsvw.adj ,采用邻接表表示法表示的图,则DFS算法如下: void DFS (ALGraph G, int v, Status ( *Visit ) (ALGraph G, int v) ) visitedv = TRUE; Visit(G, v); for ( p = G.verticesv.firstarc; p ; p = p-nextarc) if (!visitedp-adjvex ) DFS(G, p-adjvex, Visit); ,应用:图的深度优先遍历:1、 求一条包含图中所有顶点的简单路径(简单回

    15、路) 2、 判断图中是否存在环 3、 求图中通过给定顶点vk的简单回路 4、 判断是否存在从顶点vi到顶点vj的路径 5、 判别v0和v1之间是否存在一条长度为k的路径,求一条包含图中所有顶点的简单路径,1、思路 对于任意的有向图或无向图G,并不一定都能找到符合题意的简单路径。这样的简单路径要求包含G.vexnum个顶点,且互不相同。它的查找可以基于深度优先遍历。,在一个存在包含全部顶点的简单路径的图中,以下因素会影响该简单路径是否能顺利地查到: 1) 起点的选择:如图(a),其符合题意的一条简单路径如图(b)。若起点为1,则不能找到符合题意的简单路径; 2)顶点的邻接点次序:进一步考察图(a

    16、),即使以2为起点,但是2的邻接点选择的是1,而不是5,此时也不能找到符合题意的解。,在基于DFS的查找算法中,由于起点和邻接点的选取是与顶点和邻接点的存储次序以及算法的搜索次序有关,不可能依据特定的图给出特定的解决算法。因此,在整个搜索中应允许有查找失败,此时可采取回溯到上一层的方法,继续查找其他路径。 这样,引入数组Path用来保存当前已搜索的简单路径上的顶点,引入计数器n用来记录当前该路径上的顶点数。,对DFS算法的修改如下: 1) 计数器n的初始化,放在visited的初始化前后; 2) 访问顶点时,增加将该顶点序号入数组Path中,计数器n+;判断是否已获得所求路径,是则输出结束,否

    17、则继续遍历邻接点; 3) 某顶点的全部邻接点都访问后,仍未得到简单路径,则回溯,将该顶点置为未访问,计数器n-。,1),1、算法 /* 邻接矩阵表示法*/ void Hamilton(MGraph G) for ( i=0; iG.vexnum; i+ ) visitedi = FALSE; n = 0; for ( i=0; iG.vexnum; i+ ) if ( !visitedi ) DFS (G, i); void DFS(MGraph G, int i) visitedi = TRUE; Pathn = i; n+; if ( n = G.vexnum ) Print(Path);

    18、 /* 符合条件,输出该简单路径 */ for( j=0; jG.vexnum; j+ ) if ( G.arcsij.adj ,2、广度优先遍历(BFS) 方法:从图的某一顶点V0出发,访问此顶点后,依次访问V0的各个未曾访问过的邻接点;然后分别从这些邻接点出发,广度优先遍历图,直至图中所有已被访问的顶点的邻接点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止。,广度遍历:V1 V2 V3 V4 V5 V6 V7 V8,广度遍历:V1 V2 V3 V4 V5 V6 V7 V8,广度遍历:V1 V2 V3 V4 V6 V7

    19、V8 V5,广度遍历:V1 V2 V3 V4 V5 V6 V7 V8,算法思路: (1)访问V0 (2)依次访问V0 的所有邻接点v11,v12, ,v1k (3)设刚刚被访问过的一层顶点依次为vi1,vi2, ,vik则依次访问vi1,vi2, ,vik的未被访问的邻接点 (4)重复(3),广度优先遍历算法,void traver(graph G) int i;static int visitedM;for(i=1;i=n;i+)visitedi=false;for(i=1;i=n;i+)if(!visitedi)bfs(i); ,void bfs(graph G,int v0) print

    20、f(“%dn”,v); visitedv0=true; /访问顶点v0,置访问队列Q.enqueue(v0); /v0 入队while(!Q.empty( ) /队列Q不空时 v=Q.delqueue( ); /取队头w=firstadj(G,v); /取v第一个邻接点while(w!=0)if (! Visitedw)printf(“%dn“,w); visitedw=true; Q.enqueue(w); /访问W入队,置访问标志w=nextadj(G,v,w); /求下一个邻接点 ,应用:图的广度优先遍历: 1、 判断是否存在从顶点vi到顶点vj的路径 2、 求距v0的各顶点中最短路径长

    21、度最长的一个顶点。 3、 求v0和v1之间的最短路径. 4、 在顶点子集U中找出距离顶点v0最近的顶点 5、 求顶点v0到其余每个顶点的最短路径 6、 求距离顶点v0的最短路径长度为k的所有顶点,求距v0的各顶点中最短路径长度最长的一个顶点,1、思路由于题意强调为最短路径,因此应当考虑BFS的算法应用。本问题的求解转变成:从v0出发进行BFS,最后一层的顶点距离v0的最短路径长度最长。由于BFS类似于树的按层次遍历,需要引入队列用来保存本身已访问但其邻接点尚未全部访问的顶点。BFS遍历中最后一层的顶点一定是最后出队的若干顶点,队列中最后一个出队的顶点必定是符合题意的顶点。这样,只需调用BFS的

    22、算法,将最后出队的元素返回即可。,2、算法 int MaxDistance (MGraph G, int v0 ) /* 初始化各顶点的访问标志,设置为未访问 */ for ( i=0; iG.vexnum; i+ ) visitedi = FALSE; InitQueue(Q); /* 不需要考虑其他的连通分量,因为所求的顶点必定与v0在同一个连通分量中 */ EnQueue (Q, v0 ); visitedv0 = TRUE; while( !QueueEmpty(Q) ) DeQueue(Q, v); for( w=0; wG.vexnum; w+ ) if ( G.arcsvw.ad

    23、j ,7.4 最小生成树图的生成树不是唯一的,从不同的顶点出发进行遍历,可以得到不同的生成树。对于连通网络G(V,E),边是带权的,因而G的生成树的各边也是带权的。我们把生成树各边的权值总和称为生成树的权,并把权最小的生成树称为G的最小生成树(Minimum Spanning Tree)。生成树和最小生成树有许多重要的应用。令图G的顶点表示城市,边表示连接两个城市之间的通讯线路。n个城市之间最多可设立的线路有n(n-1)2条,把n个城市连接起来至少要有n-1条线路,则图G的生成树表示了建立通讯网络的可行方案。如果给图中的边都赋予权,而这些权可表示两个城市之间通讯线路的长度或建造代价,那么,如何

    24、选择n-1条线路,使得建立的通讯网络其线路的总长度最短或总代价最小呢?这就是要构造该图的一棵最小生成树。,生成树 定义:所有顶点均由边连接在一起,但不存在回路的图叫 深度优先生成树与广度优先生成树 生成森林:非连通图每个连通分量的生成树一起组成非连通图的 说明 一个图可以有许多棵不同的生成树 所有生成树具有以下共同特点: 生成树的顶点个数与图的顶点个数相同 生成树是图的极小连通子图 一个有n个顶点的连通图的生成树有n-1条边 生成树中任意两个顶点间的路径是唯一的 在生成树中再加一条边必然形成回路 含n个顶点n-1条边的图不一定是生成树,深度遍历:V1 V2 V4 V8 V5 V3 V6 V7,

    25、广度遍历:V1 V2 V3 V4 V5 V6 V7 V8,最小生成树 问题提出,要在n个城市间建立通信联络网, 顶点表示城市, 权城市间建立通信线路所需花费代价, 希望找到一棵生成树,它的每条边上的权值之和(即建立该通信网所需花费的总代价)最小最小代价生成树。,问题分析,n个城市间,最多可设置n(n-1)/2条线路, n个城市间建立通信网,只需n-1条线路, 问题转化为:如何在可能的线路中选择n-1条,能把所有城市(顶点)均连起来,且总耗费(各边权值之和)最小。,构造最小生成树方法方法一:普里姆(Prim)算法 算法思想:设N=(V,E)是连通网,TE是N上最小生成树中边的集合初始令U=u0,

    26、(u0V), TE=在所有uU,vV-U的边(u,v)E中,找一条代价最小的边(u0,v0)将(u0,v0)并入集合TE,同时v0并入U重复上述操作直至U=V为止,则T=(V,TE)为N的最小生成树 算法实现:图用邻接矩阵表示 算法描述 算法评价:T(n)=O(n),#define M 30 #define MAX 100 void minispantree_PRIM(int adM,int n) int i,j,k,p,q,wm;q=p=n-1; adqq=1;for(k=0;kq) adpq=-adpq;else adqp=-adqp; ,1,1,1,-2,1,-4,1,-1,1,-5,1

    27、,-3,方法二:克鲁斯卡尔(Kruskal)算法 算法思想:设连通网N=(V,E),令最小生成树 初始状态为只有n个顶点而无边的非连通图T=(V,),每个顶点自成一个连通分量 在E中选取代价最小的边,若该边依附的顶点落在T中不同的连通分量上,则将此边加入到T中;否则,舍去此边,选取下一条代价最小的边 依此类推,直至T中所有顶点都在同一连通分量上为止,(0)用顶点数组和边数组存放顶点和边信息 (1)初始时,令每个顶点的jihe互不相同;每个边的flag为0 (2)选出权值最小且flag为0的边 (3)若该边依附的两个顶点的jihe 值不同,即非连通,则令该边的flag=1, 选中该边;再令该边依

    28、附的两顶点的jihe以及两集合中所有顶点的jihe 相同若该边依附的两个顶点的jihe 值相同,即连通,则令该边的flag=2,即舍去该边。 (4)重复上述步骤,直到选出n-1条边为止。,顶点结点: typedef struct int data; /顶点信息int jihe; VEX;,边结点: typedef struct int vexh, vext; /边依附的两顶点int weight; /边的权值int flag; /标志域 EDGE;,算法实现:,算法描述:,1,1,1,1,1,4,2,1,1,1,2,2,2,2,2,void minitree_KRUSKAL(void) int

    29、 n,i,m,min,k,j;VEX tM;EDGE eM;printf(“Input number of vertex and edge:“);scanf(“%d,%d“,i=1;while(in) min=MAX;for(j=0;jm;j+) if(ej.weightmin ,7.5 有向无环图及应用,通常我们把计划、施工过程、生产流程、程序流程等都当成一个工程,一个大的工程常常被划分成许多较小的子工程,这些子工程称为活动,这些活动完成时,整个工程也就完成了。例如,计算机专业学生的课程开设可看成是一个工程,每一门课程就是工程中的活动,下图给出了若干门所开设的课程,其中有些课程的开设有先后关

    30、系,有些则没有先后关系,有先后关系的课程必须按先后关系开设,如开设数据结构课程之前必须先学完程序设计基础及离散数学,而开设离散数学则必须学完高等数学。我们用一种有向图来表示课程开设,在这种有向图中,顶点表示活动,有向边表示活动的优先关系,这有向图叫做顶点表示活动的网络(Activity On Vertex)简称为AOV网。,一、AOV网及拓扑排序 问题提出:学生选修课程问题顶点表示课程有向弧表示先决条件,若课程i是课程j的先决条件,则图中有弧学生应按怎样的顺序学习这些课程,才能无矛盾、顺利地完成学业拓扑排序,定义 AOV网用顶点表示活动,用弧表示活动间优先关系的有向图称为顶点表示活动的网(Ac

    31、tivity On Vertex network),简称AOV网。 若是图中有向边,则vi是vj的直接前驱;vj是vi的直接后继 AOV网中不允许有回路,这意味着某项活动以自己为先决条件 拓扑排序把AOV网络中各顶点按照它们相互之间的优先关系排列成一个线性序列的过程叫。 检测AOV网中是否存在环方法:对有向图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑有序序列中,则该AOV网必定不存在环,拓扑排序的方法 在有向图中选一个没有前驱的顶点且输出之 从图中删除该顶点和所有以它为尾的弧 重复上述两步,直至全部顶点均已输出;或者当图中不存在无前驱的顶点为止。,拓扑序列:C1-C2-C3-C4-C

    32、5-C7-C9-C10-C11-C6-C12-C8 或 :C9-C10-C11-C6-C1-C12-C4-C2-C3-C5-C7-C8,一个AOV网的拓扑序列不是唯一的,算法实现 以邻接表作存储结构 把邻接表中所有入度为0的顶点进栈 栈非空时,输出栈顶元素Vj并退栈;在邻接表中查找Vj的直接后继Vk,把Vk的入度减1;若Vk的入度为0则进栈 重复上述操作直至栈空为止。若栈空时输出的顶点个数不是n,则有向图有环;否则,拓扑排序完毕。,邻接表结点: typedef struct node int vex; /顶点域struct node *next; /链域 JD;,表头结点: typedef s

    33、truct tnode int in; /入度域struct node *link; /链域 TD; TD gM; /g0不用,算法描述,1,6,输出序列:6,输出序列:6,输出序列:6,输出序列:6,输出序列:6,输出序列:6,输出序列:6 1,输出序列:6 1,输出序列:6 1,4,输出序列:6 1,4,输出序列:6 1,4,输出序列:6 1,4,3,输出序列:6 1,4,3,输出序列:6 1,4,3,输出序列:6 1,4,3,输出序列:6 1,4,3,输出序列:6 1 3,4,3,输出序列:6 1 3,4,输出序列:6 1 3,4,输出序列:6 1 3,4,输出序列:6 1 3,4,2,

    34、输出序列:6 1 3,4,2,输出序列:6 1 3,4,2,输出序列:6 1 3 2,4,2,输出序列:6 1 3 2,4,输出序列:6 1 3 2 4,4,输出序列:6 1 3 2 4,输出序列:6 1 3 2 4,5,输出序列:6 1 3 2 4,5,输出序列:6 1 3 2 4 5,5,输出序列:6 1 3 2 4 5,算法分析,建邻接表:T(n)=O(e) 搜索入度为0的顶点的时间:T(n)=O(n) 拓扑排序:T(n)=O(n+e),void toposort(TD g,int n) int top,m,k,j;JD *p;top=0; m=0;for(j=1;j0) j=top;

    35、top=gtop.in; printf(“%dn“,j); m+; p=gj.link;while(p!=NULL) k=p-vex; gk.in-;if(gk.in=0) gk.in=top; top=k; p=p-next;printf(“m=%dn“,m);if(mn) printf(“The network has a cyclen“); ,二、关键路径 问题提出,把工程计划表示为有向图,用顶点表示事件,弧表示活动; 每个事件表示在它之前的活动已完成,在它之后的活动可以开始,例 设一个工程有11项活动,9个事件 事件 V1表示整个工程开始 事件V9表示整个工程结束 问题:(1)完成整项

    36、工程至少需要多少时间?(2)哪些活动是影响工程进度的关键?,定义 AOE网(Activity On Edge)也叫边表示活动的网。AOE网是一个带权的有向无环图,其中顶点表示事件,弧表示活动,权表示活动持续时间 路径长度路径上各活动持续时间之和 关键路径路径长度最长的路径叫 Ve(j)表示事件Vj的最早发生时间 Vl(j)表示事件Vj的最迟发生时间 e(i)表示活动ai的最早开始时间 l(i)表示活动ai的最迟开始时间 l(i)-e(i)表示完成活动ai的时间余量 关键活动关键路径上的活动叫,即l(i)=e(i)的活动,问题分析 如何找e(i)=l(i)的关键活动?,设活动ai用弧表示,其持续

    37、时间记为:dut() 则有:(1)e(i)=Ve(j)(2)l(i)=Vl(k)-dut(),如何求Ve(j)和Vl(j)?,(1)从Ve(1)=0开始向前递推,(2)从Vl(n)=Ve(n)开始向后递推,求关键路径步骤 求Ve(i) 求Vl(j) 求e(i) 求l(i) 计算l(i)-e(i),V1 V2 V3 V4 V5 V6 V7 V8 V9,0 6 4 5 7 7 16 14 18,0 6 6 8 7 10 16 14 18,a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11, ,算法实现 以邻接表作存储结构 从源点V1出发,令Ve1=0,按拓扑序列求各顶点的Vei

    38、从汇点Vn出发,令Vln=Ven,按逆拓扑序列求其余各顶点的Vli 根据各顶点的Ve和Vl值,计算每条弧的ei和li,找出ei=li的关键活动,邻接表结点: typedef struct node int vex; /顶点域int length;struct node *next; /链域 JD;,表头结点: typedef struct tnode int vexdata;int in; /入度域struct node *link; /链域 TD; TD gM; /g0不用,算法描述 输入顶点和弧信息,建立其邻接表 计算每个顶点的入度 对其进行拓扑排序 排序过程中求顶点的Vei 将得到的拓扑

    39、序列进栈 按逆拓扑序列求顶点的Vli 计算每条弧的ei和li,找出ei=li的关键活动,问题提出,用带权的有向图表示一个交通运输网,图中: 顶点表示城市 边表示城市间的交通联系 权表示此线路的长度或沿此线路运输所花的时间或费用等 问题:从某顶点出发,沿图的边到达另一顶点所经过的路径中, 各边上权值之和最小的一条路径最短路径,7.6 最短路径,1、从某个源点到其余各顶点的最短路径,13,8,13,19,21,20,迪杰斯特拉(Dijkstra)算法思想,按路径长度递增次序产生最短路径算法: 把V分成两组: (1)S:已求出最短路径的顶点的集合 (2)V-S=T:尚未确定最短路径的顶点集合 将T中

    40、顶点按最短路径递增的次序加入到S中, 保证:(1)从源点V0到S中各顶点的最短路径长度都不大于从V0到T中任何顶点的最短路径长度(2)每个顶点对应一个距离值S中顶点:从V0到此顶点的最短路径长度T中顶点:从V0到此顶点的只包括S中顶点作中间顶点的最短路径长度,依据:可以证明V0到T中顶点Vk的最短路径,或是从V0到Vk的直接路径的权值;或是从V0经S中顶点到Vk的路径权值之和 (反证法可证),求最短路径步骤 初使时令 S=V0,T=其余顶点,T中顶点对应的距离值 若存在,为弧上的权值 若不存在,为 从T中选取一个其距离值为最小的顶点W,加入S 对T中顶点的距离值进行修改:若加进W作中间顶点,从

    41、V0到Vi的距离值比不加W的路径要短,则修改此距离值 重复上述步骤,直到S中包含所有顶点,即S=V为止,1383032V2:8 ,13- 133032V1:13 ,- 13302220V3:13 ,- 192220V4:19 ,- 2120V6:20 ,算法实现 图用带权邻接矩阵存储ad 数组dist存放当前找到的从源点V0到每个终点的最短路径长度,其初态为图中直接路径权值 数组pre表示从V0到各终点的最短路径上,此顶点的前一顶点的序号;若从V0到某终点无路径,则用0作为其前一顶点的序号,算法描述,1,13,3,1,22,20,2,2,19,4,1,21,5,1,1,1,13,8,13,19

    42、,21,20,算法分析:T(n)=O(n),void shortpath_DIJ(int adM,int k,int pre, int dist,int n) int i,j,p,wm;k=k-1;for(i=0;in;i+) disti=adki;if(distiMAX) prei=k+1;else prei=0; prek=0; distk=0; adkk=1;for(j=0;j(n-1);j+) wm=MAX; p=-1;for(i=0;in;i+)if(adii=0) ,2、每一对顶点之间的最短路径 方法一:每次以一个顶点为源点,重复执行Dijkstra算法n次 T(n)=O(n) 方

    43、法二:弗洛伊德(Floyd)算法 算法思想:逐个顶点试探法 求最短路径步骤 初始时设置一个n阶方阵,令其对角线元素为0,若存在弧,则对应元素为权值;否则为 逐步试着在原直接路径中增加中间顶点,若加入中间点后路径变短,则修改之;否则,维持原值 所有顶点试探完毕,算法结束,算法实现 图用邻接矩阵存储 length存放最短路径长度 pathij是从Vi到Vj的最短路径上Vj前一顶点序号 算法描述,算法分析:T(n)=O(n),void shortpath_FLOYD(int costM,int pathM,int lengthM,int n) int i,j,k,wm;for(i=0;in;i+)f

    44、or(j=0;jn;j+) lengthij=costij;if(i=j) pathij=0;else if(lengthijMAX)pathij=i+1;else pathij=0;for(k=0;kn;k+)for(i=0;in;i+)for(j=0;jn;j+)if(lengthik+lengthkjlengthij) lengthij=lengthik+lengthkj;pathij=pathkj; ,本章小结,图是一种复杂的非线性结构,具有广泛的应用背景。本章涉及到的基本概念有: 图:由两个集合V和E组成,记为G(V,E),其中v是顶点的有穷非空集合,E是V中顶点偶对(称为边)的有穷

    45、集。通常,也将图G的顶点集和边集分别记为V(G)和E(G)。E(G)可以是空集,若E(G)为空,则图G只有顶点而没有边,称为空图。 有向图(Digraph):若图G中的每条边都是有方向的,则称G为有向图。 无向图(Undigraph):若图G中的每条边都是没有方向的,则称G为无向图。 无向完全图(Undirected Complete Graph):恰好有n(n-1)2条边的无向图称为无向完全图。 有向完全图(Directed Complete Graph):恰有n(n-1)条边的有向图称为有向完全图。,邻接点(Adjacent):若(vi,vj)是一条无向边,则称顶点vi和vj互为邻接点。

    46、度(Degree):无向图中顶点v的度是关联于该顶点的边的数目。 人度(1ndegree)若G为有向图,则把以顶点v为终点的边的数目,称为v的人度,记为ID(v)。 出度(outdegree):把以顶点v为始点的边的数目,称为v的出度,记为OD(v)。 子图(Subgraph):设G(V,E)是一个图,若v是v的子集,E是E的子集,且E中的边所关联的顶点均在v中,则G(V,E)也是一个图,并称其为G的子图。,路径(Path):在无向图G中,若存在一个顶点序列vp,vi1,vi2,vin,vq,使得(vp,vil),(vi1,vi2),(vin,vq)均属于E(G),则称顶点vp到vq存在一条路径。 路径长度:该路径上边的数目。 简单路径:若一条路径上除了vp和vq可以相同外,其余顶点均不相同,则称此路径为一条简单路径。 简单回路或简单环(Cycle):起点和终点相同(vpvq)的简单路径称为简单回路或简单环。 有根图:在一个有向图中,若存在一个顶点v,从该顶点有路径可以到达图中其它所有顶点,则称此有向图为有根图,v称作图的根。,

    展开阅读全文
    提示  道客多多所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
    关于本文
    本文标题:数据结构课件7.ppt
    链接地址:https://www.docduoduo.com/p-6844010.html
    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    道客多多用户QQ群:832276834  微博官方号:道客多多官方   知乎号:道客多多

    Copyright© 2025 道客多多 docduoduo.com 网站版权所有世界地图

    经营许可证编号:粤ICP备2021046453号    营业执照商标

    1.png 2.png 3.png 4.png 5.png 6.png 7.png 8.png 9.png 10.png



    收起
    展开