1 / 125

数据结构 第 7 章 图

数据结构 第 7 章 图. 什么是图?? 图的遍历 最短路径算法. 图( Graph )是一种较线性表和树更为复杂的非线性结构。在图结构中,对结点(图中常称为顶点)的前趋和后继个数都是不加限制的,即结点之间的关系是任意的。图中任意两个结点之间都可能相关。 图的应用极为广泛,特别是近年来的迅速发展,已渗透到诸如语言学、逻辑学、物理、化学、电讯工程、计算机科学以及数学的其它分支中。. 图. 图是由一个非空的顶点集合和一个描述顶点之间多对多关系的边(或弧)集合组成的一种数据结构,它可以形式化地表示为: 图=( V , E )

red
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章 图 • 什么是图?? • 图的遍历 • 最短路径算法 数据结构

  2. 图(Graph)是一种较线性表和树更为复杂的非线性结构。在图结构中,对结点(图中常称为顶点)的前趋和后继个数都是不加限制的,即结点之间的关系是任意的。图中任意两个结点之间都可能相关。图(Graph)是一种较线性表和树更为复杂的非线性结构。在图结构中,对结点(图中常称为顶点)的前趋和后继个数都是不加限制的,即结点之间的关系是任意的。图中任意两个结点之间都可能相关。 • 图的应用极为广泛,特别是近年来的迅速发展,已渗透到诸如语言学、逻辑学、物理、化学、电讯工程、计算机科学以及数学的其它分支中。 数据结构

  3. • 图是由一个非空的顶点集合和一个描述顶点之间多对多关系的边(或弧)集合组成的一种数据结构,它可以形式化地表示为: 图=(V,E) • 其中V={x|x某个数据对象集},它是顶点的有穷非空集合;E={(x,y)|x,yV}或E={<x,y>|x,yV且P(x,y)},它是顶点之间关系的有穷集合,也叫做边集合,P(x,y)表示从x到y的一条单向通路。 数据结构

  4. V0 V4 V3 V0 V1 V2 V3 V2 V1 图的应用举例 例1 交通图(公路、铁路) 顶点:地点 边:连接地点的公路 交通图中的有单行道双行道,分别用有向边、无向边表示; 例2 电路图 顶点:元件 边:连接元件之间的线路 例3 通讯线路图 顶点:地点 边:地点间的连线 例4 各种流程图 如产品的生产流程图 顶点:工序 边:各道工序之间的顺序关系 数据结构

  5. 通常,也将图G的顶点集和边集分别记为V(G)和E(G)。E(G)可以是空集,若E(G)为空,则图G只有顶点而没有边。通常,也将图G的顶点集和边集分别记为V(G)和E(G)。E(G)可以是空集,若E(G)为空,则图G只有顶点而没有边。 • 若图G中的每条边都是有方向的,则称G为有向图。在有向图中,一条有向边是由两个顶点组成的有序对,有序对通常用尖括号表示。例如,有序对<vi,vj>表示一条由vi到vj的有向边。有向边又称为弧,弧的始点称为弧尾,弧的终点称为弧头。 • 若图G中的每条边都是没有方向的,则称G为无向图。无向图中的边均是顶点的无序对,无序对通常用圆括号表示。 数据结构

  6. v1 v2 v1 v2 v3 v3 v4 v4 v5 (a)有向图G1(b)无向图G2 有序对<vi,vj> : 用以vi为起点、以vj为终点 的有向线段表示,称为有向 边或弧; (a)表示的是有向图G1,该图的顶点集和边集分别为: V(G1)={v1,v2,v3,v4} E(G1)={<v1,v2>,<v1,v3>,<v2,v4>,<v3,v2>} 数据结构

  7. v1 v2 v1 v2 v3 v3 v4 v4 v5 (a)有向图G1(b)无向图G2 无序对(vi,vj): 用连接顶点vi、vj的线段 表示,称为无向边; (b)表示的是无向图G2,该图的顶点集和边集分别为: V(G2)={v1,v2,v3,v4,v5} E(G2)={(vl,v2),(v1,v3),(v1,v4),(v2,v3),(v2,v5),(v4,v5)} 数据结构

  8. 在以后的讨论中,我们约定: (1)一条边中涉及的两个顶点必须不相同,即:若(vi,vj)或<vi,vj>是E(G)中的一条边,则要求vi≠vj; (2)在有向图中,一对顶点间不能有相同方向的两条有向边; (3)在无向图中,一对顶点间不能有两条无向边。 数据结构

  9. 完全图 • 若用n表示图中顶点的数目,用e表示图中边的数目,按照上述规定,容易得到下述结论: • 对于一个具有n个顶点的有向图,其边数e小于等于n(n-1),边数恰好等于n(n-1)的有向图称为有向完全图。 • 对于一个具有n个顶点的无向图,其边数e小于等于n(n-1)/2,边数恰好等于n(n-1)/2的无向图称为无向完全图; 也就是说完全图具有最多的边数,任意一对顶点间均有边相连。 数据结构

  10. v1 v1 v2 v3 v2 v3 v4 v4 (a)无向完全图G3(b)有向完全图G4 上图所示的G3与G4分别是具有4个顶点的无向完全图和有向完全图。图G3共有4个顶点6条边;图G4共有4个顶点12条边。 若(vi,vj)是一条无向边,则称顶点vi和vj互为邻接点(Adjacent),或称vi和vj相邻接;称(vi,vj)依附(Incident)于顶点vi和vj,或称(vi,vj)与顶点vi和vj相关联。 数据结构

  11. 度、入度、出度 • 在无向图中,一个顶点的度就是与该顶点相关联的边的数目,顶点v的度记为D(v)。 • 例如在上页图(a)所示的无向图G3中,各顶点的度均为3。 • 在有向图中,则把以顶点v为终点的边的数目称为顶点v的入度,记为ID(v);把以顶点v为始点的边的数目称为v的出度,记为OD(v),有向图中顶点的度数等于顶点的入度与出度之和,即D(v)=ID(v)+OD(v)。 • 例如在上页图(b)所示的有向图G4中,各顶点的度均为6。 数据结构

  12. 无论有向图还是无向图,图中的每条边均关联于两个顶点,因此,顶点数n、边数e和度数之间有如下关系:无论有向图还是无向图,图中的每条边均关联于两个顶点,因此,顶点数n、边数e和度数之间有如下关系: e= 数据结构

  13. 子图 • 给定两个图Gi和Gj,其中Gi=(Vi,Ei),Gj=(Vj,Ej),若满足ViVj,EiEj,则称Gi是Gj的子图。 数据结构

  14. v1 v2 v3 v4 v2 v3 v1 v2 v1 v2 v3 v4 v4 v2 v3 v4 v4 v2 v3 v1 v1 v4 v2 v3 v4 v4 子图示例 v1 (a)无向图G3的部分子图 v1 (b)有向图G4的部分子图 数据结构

  15. 路径 • 无向图G中若存在着一个顶点序列v、v1’、v2’、…、vm’、u,且(v,v1’)、(v1’,v2’)、…、(vm’,u)均属于E(G),则称该顶点序列为顶点v到顶点u的一条路径,相应地,顶点序列u、vm’、vm-1’、…、v1’、v是顶点u到顶点v的一条路径。 • 如果G是有向图,路径也是有向的,它由E(G)中的有向边<v,v1’>、<v1’,v2’>、…、<vm’,u>组成。 数据结构

  16. 路径长度是该路径上边或弧的数目。 • 如果一条路径上除了起点v和终点u相同外,其余顶点均不相同,则称此路径为一条简单路径。起点和终点相同(v=u)的简单路径称为简单回路或简单环。 数据结构

  17. 连通图与强连通图 • 在无向图G中,若从顶点vi到顶点vj有路径,则称vi与vj是连通的。若V(G)中任意两个不同的顶点vi和vj都连通(即有路径),则称G为连通图。例如,P6(b)所示的无向图G2、P10(a)所示的无向图G3是都是连通图。 • 无向图G的极大连通子图称为G的连通分量。 • 根据连通分量的定义,可知任何连通图的连通分量是其自身,非连通的无向图有多个连通分量。 数据结构

  18. V3 V4 V3 V4 V1 V2 V1 V2 V5 V5 例:非连通图及其连通分量示例 (a)非连通图G5(b)G5的两个连通分量H1和H2 数据结构

  19. 在有向图G中,若对于V(G)中任意两个不同的顶点vi和vj,都存在从vi到vj以及从vj到vi的路径,则称G是强连通图。在有向图G中,若对于V(G)中任意两个不同的顶点vi和vj,都存在从vi到vj以及从vj到vi的路径,则称G是强连通图。 • 有向图的极大强连通子图称为G的强连通分量。 • 据强连通图的定义,可知强连通图的唯一强连通分量是其自身,而非强连通的有向图有多个强连通分量。 数据结构

  20. v1 v2 v3 v4 v1 v2 v2 v1 v3 v4 v3 v4 (a)非强连通图G6(b)G6的两个强连通分量H3和H4 数据结构

  21. 34 V0 V2 56 25 78 V1 V3 V0 64 50 45 V1 V2 (a)无向网络G7(b)有向网络G8 网络 • 有时在图的每条边上附上相关的数值,这种与图的边相关的数值叫权。 • 权可以表示两个顶点之间的距离、耗费等具有某种意义的数。若将图的每条边都赋上一个权,则称这种带权图为网络(Network)。 数据结构

  22. 图的基本运算 • 图是一种复杂数据结构,由图的定义及图的一组基本操作构成了图的抽象数据类型。 • ADT Graph{ • 数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。 • 数据关系R: • R={<v,w>|v,wV且P(v,w),P(v,w)定义了边(或弧)<v,w>的信息} 数据结构

  23. 图的基本操作如下: (1)creatgraph(&g) 创建一个图的存储结构。 (2)insertvertex(&g,v) 在图g中增加一个顶点v。 (3)deletevertex(&g,v) 在图g中删除顶点v及所有和顶点v相关联的边或弧。 (4)insertedge(&g,v,u) 在图g中增加一条从顶点v到顶点u的边或弧。 (5)deleteedge(&g,v,u) 在图g中删除一条从顶点v到顶点u的边或弧。 数据结构

  24. (6)trave(g) 遍历图g。 (7)locatevertex(g,v) 求顶点v在图g中的位序。 (8)firstvertex(g,v) 求图g中顶点v的第一个邻接点。 (9)degree(g,v) 求图g中顶点v的度数。 (10)nextvertex(g,v,w) 求图g中与顶点v相邻接的顶点w的下一个邻接点。即求图g中顶点v的某个邻接点,它的存储顺序排在邻接点w的存储位置之后。 } ADT Graph 数据结构

  25. V0 V4 V3 V0 V1 V2 V3 如何表示顶点间的关系? V2 ? V1 图的存储结构 图的存储结构至少要保存两类信息: 1)顶点的数据 2)顶点间的关系 约定: G=<V, E>是图, V={v0,v1,v2, … vn-1 },设顶点的 角标为它的编号 数据结构

  26. 1.邻接矩阵及其实现(数组表示法) 一、非网络的邻接矩阵 给定图G=(V,E),其中V(G)={v0,…,vi,…,vn-1},G的邻接矩阵(Adjacency Matrix)是具有如下性质的n阶方阵: 无向图的邻接矩阵是对称的,有向图的邻接矩阵可能是不对称的。 数据结构

  27. v0 v2 v0 v2 v1 v1 v3 v3 0 1 1 1 1 0 1 0 1 1 0 1 1 0 1 0 0 1 0 0 1 0 1 0 1 1 0 0 0 1 0 0 A1= A2= 无向图G9及有向图G10的邻接矩阵表示 图的邻接矩阵示例 数据结构

  28. D(vi)= = OD(vi)= ; ID(vi) = • 用邻接矩阵表示图,很容易判定任意两个顶点之间是否有边相连,并求得各个顶点的度数。 • 对于无向图,顶点vi的度数是邻接矩阵中第i行或第i列值为1的元素个数,即: • 对于有向图,邻接矩阵中第i行值为1的元素个数为顶点vi的出度,第i列值为1的元素的个数为顶点vi的入度,即: 数据结构

  29. Wij当(vi,vj)或< vi,vj >E(G) ∞ 当(vi,vj)或< vi,vj >!E(G) A[i,j]= 二、网络的邻接矩阵 当G=(V,E)是一个网络时,G的邻接矩阵是具有如下性质的n阶方阵: 其中Wij表示边上的权值;∞表示一个计算机允许的、大于所有边上权值的数。 数据结构

  30. V0 64 50 34 45 V0 V2 V1 V2 56 25 78 V1 V3 ∞ 56 34 78 56 ∞ ∞ ∞ 34 ∞ ∞ 25 78 ∞ 25 ∞ ∞ ∞ 50 ∞ ∞ 45 64 ∞ ∞ A3= A4= (a)G7的邻接矩阵 (b)G8的邻接矩阵 网络邻接矩阵示例 网络的邻接矩阵示例 数据结构

  31. 邻接矩阵存储结构 #define INFINITY 5000 /*此处用5000代表无穷大*/ #define MAX_VERTEX_NUM 20 /*最大顶点数*/ typedef char vertextype; /*顶点值类型*/ typedef int edgetype; /*权值类型*/ typedef struct{ vertextype vexs[MAX_VERTEX_NUM]; /*顶点信息域*/ edgetype edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; /*邻接矩阵*/ int vexnum,arcnum; /*图中顶点总数与边数*/ } MGraph; /*邻接矩阵表示的图类型*/ 数据结构

  32. /* 图的邻接矩阵创建算法 函数名:creatmgraph1() */ #include <stdio.h> #include “MGraph.h” void creatmgraph1(MGraph *g) { int i,j,k,w; /*建立有向网络的邻接矩阵存储结构*/ printf("please input vexnum and arcnum:\n"); scanf("%d%d",&g->vexnum,&g->arcnum); /*输入图的顶点数与边数*/ printf("please input vexs:\n"); 数据结构

  33. for(i=0;i<g->n;i++) /*输入图中的顶点值*/ g->vexs[i]=getchar(); for(i=0;i<g->n;i++) /*初始化邻接矩阵*/ for(j=0;j<g->n;j++) g->edges[i][j]=INFINITY; printf("please input edges:\n"); for (k=0;k<g->e;k++) /*输入网络中的边*/ { scanf("%d%d%d", &i,&j,&w); g->edges[i][j]=w; } /*若是建立无向网,只需在此加入语句g->edges[j][i]=w即可*/ } 数据结构

  34. 说明: • 当建立有向网时,边信息以三元组(i,j,w)的形式输入,i、j分别表示两顶点的序号,w表示边上的权。对于每一条输入的边信息(i,j,w),只需将g->edges[i][j]赋值为w。 • 当建立无向网时,对每一条输入的边信息(i,j,w)后,需同时将g->edges[i][j] 和g->edges[j][i]赋值为w。 • 当建立非网络的存储结构时,所有的边信息只需按二元组(i,j)的形式输入。 数据结构

  35. 用邻接矩阵表示图时,某顶点的"第一个"邻接点就应该是该顶点所对应的行中值为非零元素的最小列号,其"下一个"邻接点就是同行中离它最近的值为非零元素的列号。用邻接矩阵表示图时,某顶点的"第一个"邻接点就应该是该顶点所对应的行中值为非零元素的最小列号,其"下一个"邻接点就是同行中离它最近的值为非零元素的列号。 数据结构

  36. 2.邻接表及其实现 用邻接矩阵表示法存储图时,占用的存储单元个数只与图中顶点的个数有关,而与边的数目无关。一个含有n个顶点的图,如果其边数比n2少得多,那么它的邻接矩阵就会有很多空元素,浪费了存储空间。 • 无向图的邻接表 对于图G中的每个顶点vi,该方法把所有邻接于vi的顶点vj链成一个带头结点的单链表,这个单链表就称为顶点vi的邻接表。单链表中的每个结点至少包含两个域,一个为邻接点域(adjvex),它指示与顶点vi邻接的顶点在图中的位序,另一个为链域(next),它指示与顶点vi邻接的下一个结点。 数据结构

  37. 1 2 3 ^ V0 v0 v2 V1 0 2 ^ V2 0 1 3 ^ v1 v3 V3 0 2 ^ 无向图G9 G9的邻接表 数据结构

  38. adjvex next vertex firstdege adjvex next 表头结点结构 边结点结构 #define MAX_VERTEX_NUM 20 /*预定义图的最大顶点数*/ typedef char datatype; /*顶点信息数据类型*/ typedef struct node{ /*边表结点*/ int adjvex; /*邻接点*/ struct node *next; }edgenode; 边结点结构 数据结构

  39. vertex firstdege typedef struct vnode{ /*头结点类型*/ datatype vertex; /*顶点信息*/ edgenode *firstedge; /*邻接链表头指针*/ }vertexnode; typedef struct{ /*邻接表类型*/ vertexnode adjlist[MAX_VERTEX_NUM]; /*存放头结点的顺序表*/ int vexnum,arcnum; /*图的顶点数与边数*/ }adjgraph; 头结点结构 数据结构

  40. 对于无向图,vi的邻接表中每个表结点都对应于与vi相关联的一条边;对于无向图,vi的邻接表中每个表结点都对应于与vi相关联的一条边; • 对于有向图来说, • 如果每一顶点vi的邻接表中每个表结点都存储以vi的为始点射出的一条边,则称这种表为有向图的出边表(也称为有向图的邻接表) • 反之,若每一顶点vi的邻接表中每个表结点都对应于以vi为终点的边(即射入vi的边),则称这种表为有向图的入边表(又称逆邻接表)。 数据结构

  41. v0 v1 v2 v3 1 ^ v0 v1 v2 v3 1 2 ^ v0 v2 0 2 ^ 3 ^ 0 2 0 v1 1 ^ 1 ^ ^ 1 ^ v3 有向图G10 G10的出边表 G10的入边表 数据结构

  42. 1 2 3 ^ V0 V1 v0 v1 v2 v3 1 ^ 0 2 ^ V2 0 2 ^ 0 1 3 ^ V3 0 1 ^ 0 2 ^ 1 ^ G10的出边表 在无向图的邻接表中,顶点vi的度为第i个链表中结点的个数;而在有向图的出边表中,第i个链表中的结点个数是顶点vi的出度;为了求入度,必须对整个邻接表扫描一遍,所有链表中其邻接点域的值为i的结点的个数是顶点vi的入度。 V0的出度为1,入度为2 V0的度为3 数据结构

  43. /* 无向图的邻接表创建算法 */ void createadjgraph(adjgraph *g){ int i,j,k; edgenode *s; printf("Please input n and e:\n"); scanf("%d%d",&g->vexnum,&g->arcnum); printf("Please input %d vertex:",g->vexnum); 数据结构

  44. for(i=0;i<g->n;i++){ scanf(“%c”,&g->adjlist[i].vertex);/*读入顶点信息*/ g->adjlist[i].firstedge=NULL; /*边表置为空表*/ } printf("Please input %d edges:",g->e); for(k=0;k<g->e;k++){ /*循环e次建立边表*/ scanf("%d%d",&i,&j); /*输入无序对(i,j)*/ s=(edgenode *)malloc(sizeof(edgenode)); s->adjvex=j; /*邻接点序号为j*/ s->next=g->adjlist[i].firstedge; g->adjlist[i].firstedge=s; /*将新结点*s插入顶点vi的边表头部*/ 数据结构

  45. s=(edgenode *)malloc(sizeof(edgenode)); s->adjvex=i; /*邻接点序号为i*/ s->next=g->adjlist[j].firstedge; g->adjlist[j].firstedge=s; /*将新结点*s插入顶点vj的边表头部*/ } } 建立无向图的邻接表算法 数据结构

  46. data firstin firstout tailvex headvex hlink tlink • 3.有向图的十字链表及其实现 虽然在有向图的邻接表和逆邻接表中分别可以找到从顶点出发的弧和指向顶点的弧,但对于同一个有向图需要用两个结构来表示它毕竟不方便,因此当应用问题中同时需要对这两种弧进行处理时就需要采用十字链表来表示有向图。 • 有向图的十字链表 在十字链表中,对应于有向图的每一个顶点有一个结点,对应于每一条弧有一个结点。 其中,firstin和firstout分别指向以该顶点为弧头或弧尾的第一个弧结点;hlink/tlink分别指向弧头/尾相同的下一条弧。 数据结构

  47. 数据结构

  48. data firstin firstout tailvex headvex hlink tlink 表头结点结构 弧结点结构 #define MAX_VERTEX_NUM 20 /*预定义图的最大顶点数*/ typedef char datatype; /*顶点信息数据类型*/ typedef struct ArcBox{ /*弧表结点*/ int tailvex, headvex; /*该弧的尾和头顶点的位置*/ struct ArcBox*hlink,*tlink;/*弧头(尾)相同的链域*/ } ArcBox; 数据结构

  49. typedef struct vnode{ /*顶点类型*/ datatype vertex; /*顶点信息*/ ArcBox *firstin,*firstout; /*指向顶点的第一条入/出弧*/ }vertexnode; typedef struct{ /*十字链表类型*/ vertexnode xlist[MAX_VERTEX_NUM]; /*存放头结点的顺序表*/ int vexnum,arcnum; /*图的顶点数与边数*/ }OLGraph; 数据结构

  50. 4. 邻接多重表 • 在邻接表中,每一条边(vi,vj)有两个结点,分别在第i和第j个链表中,这给某些图的操作带来不便。例如在需要对被搜索过的边作记号或删除一条边时,需要找到同一条边的两个结点。那么在进行此类操作时采用邻接多重表更为合适。 数据结构

More Related