1 / 110

第 7 章 图

第 7 章 图. wangzs@vip.sina.com.cn. 学习要点. 图的定义和基本术语 图的存储结构 图的遍历 图的连通性问题 有向无环图及其应用 最短路径. 重点:理解各种图的算法及其应用场合. 1 )画出 T 型路口交通管理示意图 2 )每次让三条路同时通行,那么从图看出哪些路可以同时通行. 7.1 图的定义和术语. ADT Graph{ 数据对象 V : 顶点集,是具有相同特性的数据元素的集合 数据关系 R : R={ VR }

peri
Download Presentation

第 7 章 图

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第7章 图 wangzs@vip.sina.com.cn

  2. 学习要点 • 图的定义和基本术语 • 图的存储结构 • 图的遍历 • 图的连通性问题 • 有向无环图及其应用 • 最短路径 重点:理解各种图的算法及其应用场合

  3. 1)画出T型路口交通管理示意图 2)每次让三条路同时通行,那么从图看出哪些路可以同时通行

  4. 7.1 图的定义和术语 ADT Graph{ 数据对象V:顶点集,是具有相同特性的数据元素的集合 数据关系R: R={ VR } VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧,谓词p(v,w)定义了弧<v,w>的意义或信息 } G1=(V1, VR1)其中:V1 = {A, B, C, D, E} VR1 ={<A,B>,<A,E>,<B,C>,<C,D>,<D,B>,<D,A>,<E,C>}

  5. 图的定义和术语 若弧<v,w>∈R 必有<w,v>∈R,则称 (v,w) 为顶点 v 和顶点 w 之间存在一条边。由顶点集和边集构成的图称作无向图。如上图描述为: G2=(V2, VR2) 其中: V2 ={ A, B, C, D, E, F } VR2={(A,B),(A,E),(B,E),(C,D),(D,F),(B,F),(C,F) }

  6. 图的定义 基本操作 P: CreateGraph(&G,V,VR); DestroyGraphi(&G); GetVex(G,v); LocateVex(G, u); FirstAdjVex(G, v); NextAdjVex(G, v, w); PutVex(&G, v, value); InsertVex(&G, v); DeleteVex(&G, v); InsertArc(&G, v, w); DeleteArc(&G, v, w); DFSTraverse(G, Visit()); BFSTraverse(G, Visit()); }ADT Graph

  7. 图的术语 无向图边的数目e的取值范围是:0-n*(n-1)/2 有向图的弧的数目e的取值范围是0-n*(n-1) • 完全图:有n*(n-1)/2条边的无向图 • 有向完全图:有n*(n-1)条弧的有向图 • 稀疏图与稠密图:边或弧e<n*logn的图, 反之称为稠密图 • 权:图的边或弧具有与它相关的数 • 网:带权的图 • 子图:两个图G=(V,{E})和G’=(V’,{E’}) V’是V的子集,{E’}是{E}的子集,则G’是G的子图

  8. 图的术语 例 2 4 5 1 3 6 2 2 1 3 1 3 5 3 6 例 无向完全图 有向完全图 图与子图

  9. 图的术语 路径和回路 有向路径:若有向图 G 中 k+1 个顶点之间都有弧存在,则这个顶点的序列为从顶点v0到顶点vk的一条有向路径。 无向路径:无向图,相邻顶点之间存在边的 k+1 个顶点序列构成一条长度为 k 的无向路径。 路径长度:路径中弧的数目。 简单路径:序列中的顶点都不相同。 回路或环:如果v0 和vk是同一个顶点,则是一条由某个顶点出发又回到自身的路径。 √ √

  10. 图的术语 2 4 5 1 3 6 G1 1 5 7 3 2 4 6 G2 例 路径:1,2,3,5,6,3 路径长度:5 简单路径:1,2,3,5 回路:1,2,3,5,6,3,1 简单回路:3,5,6,3 例 路径: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

  11. 图的术语 例 2 4 5 1 3 6 G1 例 1 5 7 3 2 4 6 G2 顶点的度 无向图,邻接点的个数。 有向图,出度和入度之和,其中出度定义为以该顶点为弧尾的弧的个数,入度定义为以该顶点为弧头的弧的个数。 顶点5的度:3 顶点2的度:4 顶点2入度:1 出度:3 顶点4入度:1 出度:0

  12. 图的术语 • 连通图和连通分量、强连通图和强连通分量 连通图:无向图中任意两个顶点之间存在一条无向路径 强连通图:有向图中任意两个顶点之间都存在一条有向路径。 连通分量:非连通图中各个极大连通子图。 强连通分量:有向图的极大强连通子图。

  13. 图的术语 例 2 4 5 1 3 6 例 例 2 4 5 5 1 3 6 3 6 连通图 强连通图 非连通图 强连通连通分量

  14. 图的术语 生成树--连通图的极小连通子图,它含有图中全部顶 点,但只有足以构成一棵树的n-1条边。 有向树--有向图恰有一个顶点的入度为0,其余顶点的 入度都为1 生成森林--有向图的生成森林由若干棵有向树组成, 含有图中全部顶点,但只有足以构成若干棵不相交的有 向树的弧

  15. 图的存储结构--多重链表 图没有顺序存储结构

  16. 图的存储结构--多重链表 例 V3 ^ V4 ^ V2 ^ ^ V1 1 2 例 V2 V5 ^ V4 ^ V3 ^ V1 1 2 3 4 3 G1 4 5 G2

  17. 图的存储结构--数组(邻接矩阵)表示     例 1 2  3   4 5 G2    邻接矩阵 设G=(V,E)是有n1个顶点的图,G的邻接矩阵A是具有以下性质的n阶方阵

  18. 图的存储结构--数组(邻接矩阵)表示 例 5 例 1 2 3         8 7 4 5  1 6  3 4 2  1 2  3 4   G1    

  19. 图的存储结构--数组(邻接矩阵)表示 #define INFINITY INT_MAX #define MAX_VERTEX_NUM 20 typedefenum{DG,DN,UDG,UDN} GraphKind; typedefstruct ArcCell{ //描述弧的信息 VRType adj; //顶点关系,无权图用1和0表示 InfoType *info; }ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM ] typedef struct{ VertexType vexs[MAX_VERTEX_NUM]; AdjMatrix arcs; //邻接矩阵 int vexnum, arcnum; GraphKind kind; }Mgraph;

  20. 图的存储结构--数组(邻接矩阵)表示 例: 无向图G1的数组表示存储结构为: Mgraph G1; G1. vexs=[A,B,C,D,E,F] G1.arcs= G1.vexnum=6 G1.arcnum=7 G1.kind=AD

  21. 图的邻接矩阵特点: • 无向图的邻接矩阵对称,可压缩存储;有n个顶点的无向图需存储空间为n(n+1)/2 • 有向图邻接矩阵不一定对称;有n个顶点的有向图需存储空间为n² • 无向图中顶点Vi的度TD(Vi)是邻接矩阵A中第i行元素之和 • 有向图中, • 顶点Vi的出度是A中第i行元素之和 • 顶点Vi的入度是A中第i列元素之和

  22. 图的存储结构--邻接表(链式存储结构) data firstarc adjvex next 1 2 例 3 a 4 b c d 2 4 3 1 a b c d G1 实现:为图中每个顶点建立一个单链表,第i个单链表中的结点表示依附于顶点Vi的边(有向图中指以Vi为尾的弧) ^ ^ ^ ^

  23. 图的存储结构--邻接表(链式存储结构) 1 2 2 4 4 5 3 2 3 3 5 1 例 data firstarc adjvex next a b 1 a ^ c ^ b 2 3 c ^ d e G2 4 d ^ 5 e ^

  24. 图的存储结构--邻接表(链式存储结构) adjvex nextarc info 表结点 头结点 Vexdata firstarc typedef struct ArcNode { int adjvex; struct ArcNode *nextarc; Infotype *info }ArcNode; typedef struct Vnode { VertexType vexdata; Arcnode *firstarc; }Vnode,AdjList[MAX_VERTEX_NUM]; typedef struct{ AdjList vertices; int vexnum,arcnum; int kind; }ALGraph;

  25. a b c d 4 3 1 1 a b data adjvex firstarc next 1 ^ c d 2 ^ G1 3 ^ 4 ^ • 图的邻接表特点 • 无向图中顶点Vi的度为第i个单链表中的结点数 • 有向图中 • 顶点Vi的出度为第i个单链表中的结点个数 • 顶点Vi的入度为整个单链表中邻接点域值是i的结点个数 • 逆邻接表:有向图中对每个结点建立以Vi为头的弧的单链表

  26. 图的存储结构--有向图的十字链表 例 弧结点 顶点结点 1 1 2 1 3 a tailvex headvex hlink tlink info 2 b a b 3 c c d 3 1 3 4 4 d 4 3 4 1 4 2 data firstin firstout ^ ^ ^ ^ ^ ^ ^ ^

  27. 图的存储结构--无向图的邻接多重表 边结点 顶点结点 Mark ivex ilink jvex jlink info 5 2 3 5 3 2 3 4 1 4 1 2 1 a 例 b 2 a b 3 c c 4 d d e data firstedge 5 e ^ ^ ^ ^ ^

  28. 7.3 图的遍历 图的“遍历“:对图中的每个顶点都进行一次访问且仅进行一次访问。 图的遍历除要确定一条搜索路径之外,还要解决两个问题: (1)如何确保每个顶点都被访问到; (2)如何确保每个顶点只被访问一次。

  29. 图的遍历-深度优先搜索 • 深度优先遍历(DFS) __类似于树的先序遍历 • 方法: 1、从图的某一顶点V0出发,访问此顶点; 2、然后依次从V0的未被访问的邻接点出发,深度优先遍历图,直至图中所有和V0相通的顶点都被访问到; 3、若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止 • 每个顶点设一个访问标志,以免被多次访问

  30. 图的遍历-深度优先搜索 V1 例 V2 V3 V4 V5 V6 V7 V8 V1 例 V3 V2 V5 V6 V4 V8 V7 深度遍历:V1 V2 V4  V8 V5 V6 V3 V7 深度遍历:V1 V2 V4  V8 V5 V6 V3 V7

  31. 图的遍历-深度优先搜索 V1 例 V2 V3 V4 V5 V6 V7 V8 深度遍历:V1 V2 V4  V8 V3 V6 V7 V5

  32. 开始 访问Vi,置标志 开始 求Vi邻接点 标志数组初始化 有邻接点w N Vi=1 Y 结束 Vi访问过 Y W访问过 N DFS N Y 求下一邻接点 wVi Vi=Vi+1 Vi==Vexnums DFS N Y 结束 深度优先遍历算法

  33. 深度优先遍历算法(伪码表示) void DFS(Graph G, int v) {visited[v] = TRUE; VisitFunc(v); for ( w=FirstAdjVex(G, v); w!=0; w=NextAdjVex(G, v, w) ) if (!visited[w]) DFS(G, w); } 注1:算法中函数 FirstAdjVex 和 NextAdjVex 的具体实现取决于图的存储结构。 注2:对于非连通图,如何确保每个顶点都能被访问到?

  34. 以邻接表表示的深度优先遍历 data firstarc adjvex nextarc 1 1 ^ ^ 2 2 3 3 ^ 7 8 3 6 1 5 3 7 2 8 2 3 6 5 4 1 4 2 4 4 ^ V1 例 5 5 ^ V2 V3 6 6 ^ 7 7 V4 V5 V6 V7 ^ 8 8 ^ V8 深度遍历:V1 V3  V7  V6  V2  V5  V8  V4

  35. 以邻接表表示的深度优先遍历 V1 例 V2 V3 V4 V5 V6 V7 vexdata V8 firstarc adjvex next 1 1 ^ 2 2 ^ 6 8 3 8 4 2 7 7 2 3 3 ^ 4 4 ^ 5 5 ^ 6 6 ^ 7 7 ^ 8 8 ^ 深度遍历:V1 V3  V7  V6  V2  V4  V8  V5

  36. 图的遍历-广度优先搜索 广度优先遍历(BFS)——类似树的层次遍历 • 方法: 1、从图的某一顶点出发,访问此顶点; 2、依次访问V0的各个未曾访问过的邻接点; 3、然后分别从这些邻接点出发,广度优先遍历图,直至图中所有已被访问的顶点的邻接点都被访问到; 4、若此时图中尚有顶点未被访问,则另选图中一个未被访问的顶点作起点,重复上述过程,直至图中所有顶点都被访问为止

  37. 图的遍历-广度优先搜索 V1 例 V2 V3 V4 V5 V6 V7 V8 V1 例 V3 V2 V5 V6 V4 V8 V7 广度遍历:V1 V2 V3  V4 V5 V6 V7 V8 广度遍历:V1 V2 V3  V4 V5 V6 V7 V8

  38. 图的遍历-广度优先搜索 V1 例 V2 V3 V4 V5 V6 V7 V8 广度遍历:V1 V2 V3  V4 V6 V7 V8 V5

  39. 广度优先遍历算法 开始 标志数组初始化 Vi=1 Vi访问过 N BFS Y Vi=Vi+1 Vi==Vexnums N Y 结束

  40. 广度优先遍历算法 开始 BFS 访问V0,置标志 初始化队列 V0入队 Y 队列空吗 a N 访问w,置标志 队头V出队 结束 求V邻接点w w入队 N w存在吗 V下一邻接点w Y Y w访问过 N a

  41. 广度优先遍历 例 1 2 3 4 5 f f f data firstarc 5 5 4 3 1 2 2 1 4 3 5 1 adjvex nextarc ^ 1 1 1 4 2 2 4 3 ^ 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 3 3 ^ r r r 4 4 ^ 遍历序列:1 遍历序列:1 4 5 遍历序列:1 4 3 5 ^

  42. 广度优先遍历 例 1 4 3 2 3 2 2 3 4 5 遍历序列:1 4 3 2 遍历序列:1 4 3 2 f f f vexdata 5 4 3 1 1 5 4 3 2 2 5 1 firstarc adjvex next ^ 1 1 2 2 3 2 5 ^ 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 3 3 ^ r r r 4 4 ^ 遍历序列:1 4 3 2 5 5 5 ^

  43. 广度优先遍历 例 1 2 3 4 5 f f f vexdata firstarc 5 4 1 1 5 4 2 3 3 2 5 1 adjvex next ^ 1 1 2 2 ^ 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 5 2 5 3 3 ^ r r r 4 4 ^ 5 5 ^ 遍历序列:1 4 3 2 5 遍历序列:1 4 3 2 5 遍历序列:1 4 3 2 5

  44. 广度优先遍历 vexdata firstarc adjvex next 1 1 ^ 2 2 ^ 2 8 3 6 7 8 2 4 7 3 3 ^ 4 4 ^ 5 5 ^ 6 6 ^ 7 7 ^ 8 8 ^

  45. 7.4 图的连通性问题 V1 V1 V2 V3 V2 V3 V4 V5 V6 V7 V4 V5 V6 V7 V1 V8 V1 V8 V2 V3 V2 V3 V4 V6 V4 V5 V6 V7 V1 例 V8 V7 V2 V3 V8 V5 V4 V5 V6 V7 V8 深度遍历:V1 V2 V4  V8 V5 V3 V6 V7 广度遍历:V1 V2 V3  V4 V5 V6 V7 V8 广度优先生成树 深度优先生成树

  46. A B C D E F G H D A I K L C F E J M L M B J G K I H 深度优先生成森林

  47. 生成树 • 深度优先生成树与广度优先生成树 • 生成森林:非连通图每个连通分量的生成树一起组成非连通图的生成森林。 • 说明 • 一个图可以有许多棵不同的生成树 • 所有生成树具有以下共同特点: • 生成树的顶点个数与图的顶点个数相同 • 生成树是图的极小连通子图 • 一个有n个顶点的连通图的生成树有n-1条边 • 生成树中任意两个顶点间的路径是唯一的 • 在生成树中再加一条边必然形成回路 • 含n个顶点n-1条边的图不一定是生成树

  48. 7.4.3 最小生成树 7 1 2 7 5 9 13 24 6 5 10 17 12 3 4 18 • 问题提出 要在n个城市间建立通信联络网, 顶点——表示城市 权——城市间建立通信线路所需花费代价 希望找到一棵生成树,它的每条边上的权值之和(即建立 该通信网所需花费的总代价)最小———最小代价生成树 • 问题分析 n个城市间,最多可设置n(n-1)/2条线路 n个城市间建立通信网,只需n-1条线路 问题转化为:如何在可能的线路中选择n-1条,能把所有城市(顶点)均连起来,且总耗费(各边权值之和)最小

  49. 最小生成树 • 构造最小生成树方法 • 方法一:普里姆(Prim)算法 • 算法思想:设N=(V,{E})是连通网,TE是N上最小生成树中边的集合 • 初始令U={u0},(u0V), TE= • 在所有uU,vV-U的边(u,v)E中,找一条代价最小的边(u0,v0) • 将(u0,v0)并入集合TE,同时v0并入U • 重复上述操作直至U=V为止,则T=(V,{TE})为N的最小生成树

  50. 最小生成树 1 1 例 5 6 1 1 5 2 4 5 5 3 3 3 3 2 4 6 6 5 6 1 1 1 1 1 1 2 4 4 1 1 2 4 3 5 3 3 2 2 3 4 2 4 4 4 5 6 6 6 6 1

More Related