学习 严蔚敏讲数据结构笔记14

第七章图

7.1抽象数据类型图的定义

7.2图的存储表示

7.3图的遍历

7.4最小生成树

7.5重(双)连通图和关节点

7.6两点之间的最短路径问题

7.7拓扑排序

7.8关键路径

 

7.1抽象数据类型图的定义

ADT Graph

{

         数据对象VV是具有相同特性的数据元素的集合,称为顶点集。

         数据关系R:R={VR}VR={<v,w>|v,wVP(v,w),<v,w>表示从vw的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}

}

名词和术语

弧头、弧尾、弧、有向图

边,无向图

网,子图

完全图,稀疏图,稠密图

邻接点,度,入度,初度

路径,路径长度,简单路径,简单回路

连通图,连通分量,强连通图,强连通分量

生成树,生成森林

 

<v,w>VR,则<v,w>表示匆匆顶点v到顶点w的一条弧,称顶点v为弧尾,顶点w为弧头。有顶点集和弧集构成的图称为有向图。

<v,w>VR必有<w,v>VR,则称(v,w)为顶点v和顶点w之间存在一条边。

由顶点集和边集构成的图称作无向图。

弧或边带权的图分别称作有向网或无向网。

设图G=(V,{VR})和图G’=(V’,{VR’}),V’包含于VVR包含于VR’则称G’G的子图。

假设图中有n个顶点,e条边,则

含有e=n(n-1)/2条边的无向图称作完全图

含有e=n(n-1)条弧的有向图称作有向完全图

若边或弧的个数e<nlogn,则称作稀疏图,否则称作稠密图。

无向图

假若顶点v和顶点w之间存在一条边,则称顶点v和顶点w互为邻接点,边(v,w)和顶点vw相关联。

和顶点v关联的边的数目定义为边的度。

对有向图来说,

以顶点v为弧尾的弧的数目定义为顶点的出度,以顶点v的弧头的弧的数目定义为顶点的入度。度(TD)=入度(OD)+出度(ID)

设图G=(V,{VR})中的一个顶点序列{u=vi,0, vi,1, …, vi,m = w}(vi,j-1, vi,j)VR,1<=j<=m,则称从顶点u到顶点v之间存在一条路径,路径上边的数目称作路径长度。

若序列中的顶点不重复出现,则称作简单路径。

u=w,则称这条路径为回路或简单回路。

若图G中任意两个顶点之间都有路径相同,则称此图为连通图;

若无向图为非连通图,则图中各个极大连通图子图称作此图的连同分量。

对有向图,若任意两个顶点之间都存在一条有向路径,则称此有向图为强连通图,否则,其各个强连通子图称作它的强连通分量。

假设一个连通图有n个顶点和e条边,其中n-1条边和n个顶点构成一个极小连通子图,称该极小连通子图为此连通图的生成树。

对非连通图,则称各个连同分量的生成树的集合为此非连通图的生成森林。

基本操作:

结构的建立和销毁

CreateGraph(&G, V, R);

DestroyGraph(&G);

对顶点的访问操作

LocateVex(G, u);

GetVex(G, v);

PutVex(&G, v, value);

对邻接点的操作

FirstAdjVex(G, v);

NextAdjVex(G, v, w);

插入或删除顶点

InsertVex(&G, v);

DeleteVex(&G, v);

插入和删除弧

InsertArc(G, v, w);

DeleteArc(&G, v, w);

遍历

DFSTraverse(G, v, Visit());

BFSTraverse(G, v, Visit());

 

对顶点的访问操作

LocateVex(G, u); //G中存在顶点u,则返回该顶点在图中位置;否则返回其它信息。

GetVex(G, v); //返回v的值

PutVex(&G, v, value); //v赋值value

对邻接点的操作

FirstAdjVex(G, v); //返回v的第一个邻接点。若该顶点在G中没有邻接点,则返回“空”。

NextAdjVex(G, v, w); //返回v的(相对于w的)下一个邻接点。若wv的最后一个邻接点,则返回“空”。

插入或删除顶点

InsertVex(&G, v); //在图G中增添新顶点v

DeleteVex(&G, v);//删除G中顶点v及其相关的弧。

插入和删除弧

InsertArc(&G, v, w); //G中增添弧<v,w>,若G是无向的,则还增添对称弧<w,v>

DeleteArc(&G, v, w);//G中删除弧<v,w>,若G是无向的,则还删除对称弧<w,v>

遍历

DFSTraverse(G, v, Visit()); //从顶点v起深度优先遍历图G,并对每个顶点调用函数Visit一次且仅一次。

BFSTraverse(G, v, Visit());//从顶点v起广度优先遍历图G,并对每个顶点调用函数Visit一次且仅一次。

 

7.2图的存储表示

一、图的数组(邻接矩阵)存储表示。

25_001

typedef struct ArcCell

{

         VRType  adj; //VRType是顶点关系类型,对无权图,用10表示相邻与否;对带权图,则为权值类型

         InfoType  *info; //该弧相关信息的指针

}ArcCell,  AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];

typedef struct

{

         Vertex  vexs[MAX_VERTEX_NUM];

         AdjMatrix  arcs;

         int  vexnum, arenum;

         GraphKind  kind;

}MGraph;

二、图的邻接表存储表示

25_002

typedef struct ArcNode

{

         int  adjvex; //该弧所指向的顶点的位置

         struct  ArcNode *nextarc; //指向下一条弧的指针

         InfoType  *info; //该弧相关信息的指针

}ArcNode;

typedef struct VNode

{

         VertexType  data; //顶点信息

         ArcNode  *firstarc; //指向第一条依附该顶点的弧

}VNode, AdjList[MAX_VERTEX_NUM];

typedef struct

{

         AdjList  vertices;

         int  vernum, arcnum;

         int  kind; //图的种类标志

}ALGraph;

三、有向图的是自链表存储表示

25_003

typedef struct ArcBox

{

         int  tailvex, headvex; //该弧的弧尾和头顶点的位置

         struct  ArcBox *hlink, *tlink; //分别指向下一个弧头相同弧尾相同弧的指针域

         InfoType  *info; //该弧相关信息的指针

}ArcBox;

 

typedef struct VexNode

{

         VertexType  data;

         ArcBox  *firstin, *firstout;

}VexNode;

 

typedef struct

{

         VexNode  xlist[MAX_VERTEX_NUM];

         int  vexnum, arcnum; //有向图的当前顶点数和弧数

}OLGraph;

一、无向图的邻接多重表存储表示

25_004

typedef struct Ebox

{

         VisitIf  mark; //访问标记

         int  ivex,jvex; //访问依附两个顶点的位置

         struct  EBox *ilink, *jlink;

         InfoType  *info; //该边信息指针

}EBox;

 

typedef struct VexBox

{

         VertexType  data;

         EBox  *firstedge; //指向第一条依附该顶点的边

}VexBox;

 

typedef struct

{

         VexBox  adjmulist[MAX_VERTEX_NUM];

         int  vexnum, edgnum;

}AMLGraph;

 

7.3图的遍历

从图中某个顶点出发游历图,访遍图中其余顶点,并且使图中的每个顶点仅被访问一次的过程。

深度优先搜索

广度优先搜索

遍历应用举例

 

从图中某个顶点V0 出发,访问此顶点,然后依次从V0 的各个未被访问的邻接点出发深度优先搜索遍历图。,直至图中所有和V0有路径想通的顶点都被访问到,若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为起始点,重复上述过程,直至图中所有顶点都被访问到为止。

 

 

26_001

void DFSTraverse(Graph G, Status(*  Visit)(int v))

{

         //对图G作深度优先遍历

         VisitFunc  = Visit;

         for(v  = 0; v < G.vexnum; ++ v)

         {

                   visited[v]  = FALSE; //访问标志数组初始化

         }

         for(v  = 0; v < G.vexnum; ++ v)

         {

                   if(!  visited[v]

                   {

                            DFS(G,  v); //对尚未访问的顶点调用DFS

                   }

         }

}

 

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); //v的尚未访问的邻接顶点w递归调用DFS

                   }

         }

}

你可能感兴趣的:(学习 严蔚敏讲数据结构笔记14)