数据结构:图.ppt
《数据结构:图.ppt》由会员分享,可在线阅读,更多相关《数据结构:图.ppt(103页珍藏版)》请在三一办公上搜索。
1、第七章 图,图(Graph)是一种较线性结构和树型结构更为复杂的数据结构,图中任意两个结点之间都可以直接相关。图的用途极其广泛,已渗入到电讯工程、计算机科学以及数学等分支学科当中。在本课程当中,我们主要讨论如何在计算机上实现图的存储和操作。,第七章 图,1、图的定义和术语2、图的存储结构3、图的遍历4、图的遍历应用:(1)图的连通分量(2)最小生成树(3)双重连通图5、图的遍历应用:最短路径6、图的遍历应用:拓扑排序、关键路径,7.1 图的概念和术语:图中结点之间的关系是任意的,任意两个数据元素之间都可能相关。,图:由一个顶点集 V 和一个边集E构成的数据结构。表示:G=(V,E)顶点图中的数
2、据元素;V(G)-顶点的非空有穷集合;边相关顶点的偶对;E(G)-边的有穷集合。有向图:图中的边是顶点的有序对。弧-有向图的边,如:始点(尾顶点)Vi由Vi射出的弧的顶点。终点(头顶点)Vj弧射入的顶点。无向图:边是顶点的无序对。如:(Vi,Vj),无向图,有向图,约定:不考虑顶点到其自身的边,也不允许一条边在图中重复出现(即若(Vi,Vj)或是E(G)中的一条边,则要求ViVj),并设图G的顶点数为n,边数为e,则有如下性质:无向图:最多有n(n-1)/2条边,即:0en(n-1)/2有向图:最多有n(n-1)条边,即:0en(n-1),证明无向图的最大边数:最多有n(n-1)/2条边,即:
3、0en(n-1)/2。证明:当顶点数 K=2时,只有一条边,结论正确;设当 K=n-1时,结论正确,即有:Emax=(n-1)(n-2)/2令:K=(n-1)+1=n,因为在由(n-1)个顶点组成的无向图中增加一个顶点(变为有n个顶点的无向图),最多增加n-1条边。显然有:Emax=(n-1)(n-2)/2+(n-1)=n(n-1)/2 证毕,证明有向图的最大边数:最多有n(n-1)条边,即:0en(n-1)。证明:当顶点数 K=2时,可有两条边,结论正确;设当 K=n-1时,结论正确,即有:Emax=(n-1)(n-2)令:K=(n-1)+1=n,因为在由(n-1)个顶点组成的有向图中增加多
4、一个顶点(变为有n个顶点的有向图),最多增加2*(n-1)条边。显然有:Emax=(n-1)(n-2)+2*(n-1)=n(n-1)证毕。,完全图:任意一对顶点间均有边相连,具有最大边数。无向完全图:有n(n-1)/2条边的无向图。有向完全图:有n(n-1)条边的有向图。相邻顶点(邻接点):当E或(Vi,Vj)E,则称Vi,Vj是相邻顶点,弧 或边(Vi,Vj)是与顶点Vi和Vj相关联的边。顶点(V)的度:与顶点(V)相关联的边的数目,记为TD(V)。出度OD(V):在有向图中,把以顶点V为尾的弧的数目称为顶点V的出度。入度ID(V):在有向图中,把以顶点V为头的弧的数目称为顶点V的入度。TD
5、(V)=OD(V)+ID(V),性质:设G有n个顶点,e条边或弧,则:,子图:设G=(V,E)是一个图,若:V是V的子集,E是E的子集,且E中的边所关联的顶点均在V中,则:G=(V,E)是 G=(V,E)子图。,路径:由G 中顶点Vi到达Vj经过的顶点序列。,如上图所示:V1-V3-V4是V1到V4的一条路径,同理:V1-V2-V3-V4也是V1到V4的一条路径。,路径长度:路径上边的数目。Internet上从IP路由到IP路由称为一跳(hop),如上图所示:V1-V3-V4为hop=2:V1-V2-V3-V4为hop=3;V1-V4为hop=1,简单路径:一条路径上的顶点除起始顶点和终结顶点
6、可相同外,其它顶点都不相同。例如:下图中的V1-V3-V4、V1-V2-V3-V4、V1-V4均为简单路径。,图G,回路(环):起始顶点和终结顶点可相同的简单路径。如上图所示:V1-V3-V4-V1、V1-V2-V3-V4-V1 均为环。,连通图:图G中任意两个顶点Vi、Vj(ViVj)都是连通的(可达的)。,连通分量:无向图的极大连通子图,A,B,C,D,E,F,G,I,J,L,H,M,K,A,B,C,D,E,H,M,F,G,I,J,L,K,无向图G,无向图G的三个连通分量,强连通图:有向图图 G 的任意两点之间都是连通的,则称 G 是强连通图。强连通分量:有向图的极大连通子图,V1,V3,
7、V4,1,带权图(网络):图中每一条边附加一个数作为权(可以表示一个顶点到另一个顶点的距离、代价等)。,生成树:极小连通子图。包含图的所有 n 个结点,但只含图的 n-1 条边。在生成树中加一条边之后,必定会形成回路或环。,稀疏图:若边或弧的个数 e=nlogn,图的抽象数据类型定义:参见课本,图的四种常用的存储形式:邻接矩阵和加权邻接矩阵邻接表十字链表邻接多重表,7.2 图的存储结构:,邻接矩阵(n个顶点用n阶方阵表示):便于判断两顶点是否相邻,并计算各自的度。1(Vi,Vj)或是E(G)的边或弧Ai,j=0 其它,0 1 1 00 0 0 00 0 0 11 0 0 0,网络的邻接矩阵,在
8、C 语言中,实现邻接矩阵表示法的类型定义如下所示:#define MAX 20typedef struct graph EntryType itemMAXMAX;int n;Graph;,顶点Vi的度的计算:无向图:为第i行元素之和,有向图:入度=第i列元素之和;出度=第i行元素之和。,邻接矩阵存储:优点:判断任意两点之间是否有边方便,仅耗费 O(1)时间;插入、删除一条边简单。适合于图的规模稳定、稠密图。缺点:即使 n2 条边,也需内存 n2/2 单元,太多;仅读入数据耗费 O(n2)时间,太长。,图的邻接表存储表示,adjvex nextarc,边结点表示:,7条边却用了 14 个边结点!
9、改进:建立邻接多重表,有向图的邻接表,可见,在有向图的邻接表中不易找到指向该顶点的弧。改进:建立逆邻接表或十字链表,有向图的逆邻接表,在有向图的邻接表中,对每个顶点,链接的是指向该顶点的弧,边的结点结构,typedef struct EdgeNode int data;struct EdgeNode*next;InfoType*info;EdgeNode;,vertex firstarc,顶点的结点结构,typedef struct VNode VertexType vertex;EdgeNode*firstarc;VNode,图的定义:typedef struct VNode AdjList
10、MAX_NUM;int vexnum,arcnum;int kind;/图的种类标志 ALGraph,适应于:经常计算顶点的度;顶点数目不确定;经常遍历图;稀疏图。,有向图的十字链表存储表示,0 1 2,弧的结点结构,指向下一个有相同弧尾的结点,指向下一个有相同弧头的结点,typedef struct ArcBox/弧的结构表示 int tailvex,headvex;InfoType*info;struct ArcBox*hlink,*tlink;VexNode;,tailvex,headvex,hlink,tlink,info,顶点的结点结构,指向该顶点的第一条入弧,指向该顶点的第一条出弧
11、,typedef struct VexNode/顶点的结构表示 VertexType data;ArcBox*firstin,*firstout;VexNode;,data,firstin,firstout,typedef struct VexNode xlistMAX_VERTEX_NUM;/顶点结点(表头向量)int vexnum,arcnum;/有向图的当前顶点数和弧数 OLGraph;,有向图的结构表示(十字链表),四、无向图的邻接多重表存储表示,用途:用于无向图,边表中的边结点只需存放一次,节约内存。,typedef struct Ebox VisitIf mark;/访问标记 in
12、t ivex,jvex;/该边依附的两个顶点的位置 struct EBox*ilink,*jlink;InfoType*info;/该边信息指针 EBox;,边的结构表示,typedef struct/邻接多重表 VexBox adjmulistMAX_VERTEX_NUM;int vexnum,edgenum;AMLGraph;,顶点的结构表示,typedef struct VexBox VertexType data;EBox*firstedge;/指向第一条依附该顶点的边 VexBox;,无向图的结构表示,7.3 图的遍历,从图中某个顶点出发游历图,访遍图中其余顶点,并且使图中的每个顶点
13、仅被访问一次的过程。常见的图遍历方式有两种:深度优先遍历和广度优先遍历,这两种遍历方式对有向图和无向图均适用。,深度优先遍历(Depth First Search,简称DFS)首先访问顶点V,再访问一个与V相邻的且未被访问的顶点W,接着访问一个与W相邻且未被访问的顶点,依次类推,直到某个被访问的顶点的所有相邻顶点均被访问过。然后回退到尚有相邻顶点未被访问的顶点R,再由R出发进行上述DFS;重复上述过程,直到图中所有顶点都被访问过。,深度优先遍历,深度优先遍历,1,4,3,7,6,2,5,从V1出发进行DFS,得:V1,V2,V6,V5,V7,V3,V4,W1、W2和W3 均为 V 的邻接点,S
14、G1、SG2 和 SG3 分别为含顶点W1、W2和W3 的子图。,访问顶点 V;for(W1、W2、W3)若该邻接点W未被访问,则从它出发进行深度优先搜索遍历。,深度优先遍历DFS算法:,从上页的图解可见:,1.从深度优先搜索遍历连通图的过程类似于树的先根遍历;,解决的办法是:为每个顶点设立一个“访问标志 visitedw”;,2.如何判别V的邻接点是否被访问?,首先将图中每个顶点的访问标志设为 FALSE,之后搜索图中每个顶点,如果未被访问,则以该顶点为起始点,进行深度优先搜索遍历,否则继续检查下一顶点。,非连通图的深度优先搜索遍历,T,T,T,T,T,T,T,T,T,a,c,h,d,k,f
15、,e,b,g,a,c,h,k,f,e,d,b,g,访问标志:,访问次序:,例如:,a,c,h,d,k,f,e,1,2,4,3,V1,V3,V4,V2,深度优先遍历DFS的递归算法:,1,2,3,1,2,0,2,3,4,0,1,3,0,2,Data link,0123,顶点序号,Vex link,输出序列:V1V2V3V4,#define MaxVertexNum 20typedef struct graph VertexType vexsMaxVertexNum;int edgesMaxVertexNumMaxVertexNum;int n;Graph;void DFSM(Graph*G,in
16、t i)/以vi为出发点对邻接矩阵表示的图G进行搜索,设邻接矩阵是0,l矩阵 int j;printf(visit vertex:c,G-vexsi);/访问顶点vi visitedi=TRUE;for(j=0;jn;j+)/依次搜索vi的邻接点 if(G-edgesij=1&!visitedj)DFSM(G,j)/DFSM,typedef struct EdgeNode int adjvex;struct EdgeNode*next;EdgeNode;/边结点定义typedef struct VNode VertexType vertex;EdgeNode*firstedge;VNode/单
17、链表头的定义 typedef struct VNode AdjListMAX_VERTEX_NUM;int vexnum,arcnum;int kind;/图的种类标志 ALGraph;/图的定义typedef enumFALSE,TRUEBoolean;Boolean visitedMaxVertexNum;/访问标志的定义,void DFSTraverse(ALGraph*G)int i;for(i=0;iVexnum;i+)visitedi=FALSE;for(i=0;iVexnum;i+)if(!visitedi)DFS(G,i);/以vi为源点开始DFS搜索/DFSTraversev
18、oid DFS(ALGraph*G,int i)EdgeNode*p;printf(“visit vertex:c”,G-adjlisti.vertex);visitedi=TRUE;/标记vi已访问p=G-adjlisti.firstedge;/取vi边表的头指针while(p)if(!visitedp-adjvex)DFS(G,p-adjvex);else p=p-next;/找vi的下一邻接点/DFS,void StackPreorder(BiTree T)STACK s;BiTree p;InitStack(s);Push(s,T);while(!StackEmpty(s)Pop(s,
19、p);printf(%4d,p-data);if(p-rchild)Push(s,p-rchild);if(p-lchild)Push(s,p-lchild);,深度优先遍历过程中,后访问的顶点其邻接点被先访问,即“先被访问的顶点的邻接点”要后于“后被访问的顶点的邻接点”被访问,故在递归调用过程中使用栈来保存已访问的顶点。算法思想:(1)从V出发,visitedv=true,访问并入栈push(S,v);(2)栈非空时,读取栈顶元素GetTop(S,w)从w出发,若w存在未被访问的邻接点v,则:访问v,修改v的访问标志,v入栈;否则,当前栈顶退栈。,深度优先遍历DFS的非递归算法:,void
20、DFS(ALGraph*G,int i)EdgeNode*p;int w;STACK S;InitStack(S);printf(“visit vertex:%c”,G-adjlisti.vertex);visitedi=TRUE;Push(S,i);w=i;while(!StackEmpty(S)GetTop(s,w);p=G-adjlistw.firstedge;while(p/DFS,广度优先遍历Breadth First Search,算法思想:(1)从某一顶点V出发,首先访问该顶点,然后依次访问与起始顶点相通的未访问过的相邻顶点W1,W2,.,Wn;(2)依次访问相邻顶点W1,W2,
21、.,Wn的未被访问过的相邻顶点,依次类推,直到图中所有未被子访问过的顶点的相邻顶点都被访问过。(3)若图中仍有顶点未被访问过,则另选图中一个未被访问过的顶点作起始顶点,重复上述过程(1)、(2),直到图中所有顶点都被访问过。,广度优先遍历,1,4,3,7,6,2,5,从V1出发进行BFS,得:V1,V2,V3,V4,V5,V6,V7。,1,3,4,2,5,从V1出发进行BFS,得:V1,V2,V3,V4,V5,若w1先于w2访问,则w11w1n也先于w21.w2n的访问。显然,按广度优先遍历是类似于树的层次遍历的。(1)对于广度优先遍历,其关键之处在于怎么保证“先被访问的顶点的邻接点”要先于“
22、后被访问的顶点的邻接点”被访问。也就是先到先被访问,这正好是队列的特点,因此可以使用队列来实现(2)在广度优先遍历过程中同深度优先遍历一样,为了避免重复访问某个顶点,也需要visited0.n-1(n是图中顶点的数目),用来记录每个顶点是否已经被访问过。,广度优先遍历Breadth First Search BFS算法:,1,3,4,2,5,1,2,3,4,12345,2,Data link,3,4,1,5,5,1,5,1,5,2,3,4,Vex link,gv,void BFS(ALGraph*G,int k)int i;EdgeNode*p;InitQueue(Q);printf(visi
23、t vertex:c,G-adjlistk.vertex);visitedk=TRUE;EnQueue(Q,k);while(!QueueEmpty(Q)DeQueue(Q,i);/相当于vi出队p=G-adjlisti.firstedge;/取vi的边表头指针while(p)if(!visitedp-adjvex)printf(“visitvertex:%c”,G-adjlistp-adjvex.vertex);visitedp-adjvex=TRUE;EnQueue(Q,p-adjvex);/访问过的vj人队 p=p-next;/找vi的下一邻接点,时间复杂度:考察无向图(邻接表)Bfs(
24、)的初始化:o(n+e)Bfs()的迭代 外循环:每个顶点只进入1次,累计n次 内循环(枚举v的每一个邻居),累计deg(v)次总共:有向图相同,若邻接矩阵存储呢?Dfs()呢?,遍历算法的应用,连通图的生成树:DFS/BFS非连通图的生成森林:DFS/BFS连通性检测:DFS/BFS无向图环路检测:DFS/BFS有向图环路检测:DFS顶点之间可达性检测/路径求解:DFS/BFS顶点之间的最短距离:BFS拓扑排序:DFS,7.4 图的连通性问题,一、无向图的连通分量和生成树1.概念:对于无向图G从一个顶点出发进行一次深度(广度)优先遍历得到的顶点序列,加上依附于这些顶点的边就构成了图G的一个连
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构
![提示](https://www.31ppt.com/images/bang_tan.gif)
链接地址:https://www.31ppt.com/p-3788006.html