- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
0
邻接矩阵的存储结构
#define MAX_VERTEX_NUM 20 //最大顶点个数 #define INFINITY INT_MAX typedef enum{DG, DN, UDG, UDN} GraphKind; /*图的种类*/ #define MAX_VERTEX_NUM 20 //最大顶点个数 typedef char VertexData; /*假设顶点数据为字符型*/
7.3.2 广度优先搜索
广度优先搜索(breadth-first search,简称 广度优先搜索 ,简称BFS)
从图中的某个顶点v出发,访问并标记了顶点v之后 横向搜索v的所有邻接点u1,u2,…,ut 在依次访问v的各个未被访问的邻接点之后,再从这 些邻接点出发,依次访问与它们邻接的所有未曾访 问过的顶点 重复上述过程直至图中所有与源点v有路径相通的顶 点都被访问为止
�
7.3.1 深度优先搜索
深度优先搜索(depth-first search,简称DFS) 类似于树的先根次序遍历.深度优先搜索方法 的特点是尽可能先对纵深方向进行搜索. 基本思想
访问顶点v; 依次从v的未被访问的邻接点出发,对图进行深度优 先遍历;直至图中和v有路径相通的顶点都被访问; 若此时图中尚有顶点未被访问,则从一个未被访问 的顶点出发,重新进行深度优先遍历,直到图中所 有顶点均被访问过为止.
VisitFunc = Visit; for (v=0; v<G.vexnum; ++v) visited[v]=0; for (v=0; v<G.vexnum; ++v) if (!visited[v]) DES(G,v);
} void DFS(Graph G, int v) {//从第v个顶点出发DFS遍历
邻接矩阵实例
V1 V2 V1 V3 V3
有向图 G1
V2
V4
V4
V5
无向图 G2
邻接矩阵存储结构的特点
无向图
无向图邻接矩阵是对称阵,每条边存储两次; 顶点v的度等于二维数组对应行(或列)中值为1的 元素个数; 判断两顶点v,u是否为邻接点:只需判二维数组对 应分量是否为1; 顶点不变,在图中增加,删除边:只需对二维数组 对应分量赋值1或清0; 设图的顶点数为 n ,用有n个元素的一维数组存储图 的顶点,用邻接矩阵表示边,则G占用的存储空间为: n+n2;图的存储空间占用量只与它的顶点数有关, 与边数无关;适用于边稠密的图;
第七章 图
软件学院 成少雷
7.1 7.2 7.3 7.4 7.5 7.6
基本概念和术语 图的存储结构 图的遍历 最小代价生成树 拓扑排序,关键路径 最短路径
7.1 基本概念和术语
图是顶点集和边集组成的二元组G=<V,E>
顶点 数据元素通常称作顶点(vertex),V就是顶点 的有穷非空集合. 顶点的序偶,称之为边(edge) E 边(edge),E是边的集合 .
V1 V2 V3 从顶点v1出发进行BFS遍历 V4 V5 V6 V7
V8 V2
V1 V3
V4 V8
V5
V6
V7
void BFSTraverse(Graph G, Status (* visit)(int v)) { for(v=0; v<G.vexnum; ++v) visited[v] = FALSE; IntiQueque(Q); for(v=0; v<G.vexnum; ++v) if(!visited[v]) { EnQueue(Q,v); while(!QueueEmpty(Q)){ DeQueue(u); visited[u] = TRUE; Visit (u); for(w=FirstAdjVex(G, u); w; w = NextAdjVex(G,u,w)) if(!visited[w]) {visited[w]=TRUE; visited(w); EnQueue(G,w); } } } }
有向图
有向图的邻接矩阵不一定是对称的; 顶点v的出度(OD(v)):等于二维数组对应行中值为1 的元素个数; 顶点v的入度(ID(v)):等于二维数组对应列中值为1 的元素个数; 顶点v的度TD(v) = OD(vi) + ID(vj)
网的Βιβλιοθήκη Baidu接矩阵
V1 3 V6 1 V5 6 5 (a) 网 V4 (b) 邻接矩阵 5 8 7 9 V3 5 V2 4 ∞ ∞ 8 ∞ ∞ 3 5 ∞ ∞ ∞ ∞ ∞ ∞ 4 ∞ 5 ∞ ∞ 7 ∞ ∞ ∞ ∞ ∞ ∞ ∞ 9 ∞ ∞ 6 5 ∞ ∞ ∞ 1 ∞
0 1
0 2
∧
2 3 ∧∧ 3 1∧ 3 2 ∧∧
7.1 7.2 7.3 7.4 7.5 7.6
基本概念和术语 图的存储结构 图的遍历 最小代价生成树 拓扑排序,关键路径 最短路径
7.3 图的遍历
图的遍历是指从图中的某一个顶点出发,按照 一定的策略访问图中的每一个顶点,使得每一 个顶点访问且只被访问一次.图的遍历算法是 求解图的连通性问题,拓扑排序和关键路径等 问题的基础. 深度优先搜索和广度优先搜索 广度优先搜索是图的两种基本 深度优先搜索 广度优先搜索 遍历方法,对有向图和无向图都适用.
typedef enum {DG,DN,AG,AN} GraphKind;//图的类型 typedef struct ArcCell { /*对于无权图,用1或0表示是否相邻;对带权图,则为权值*/ VRType adj;//顶点关系类型,对无权图用1或0表示是否相邻 int ArcNode[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; InfoType *info;//该弧的其他信息 }ArcCell, AdjMatrix[Max_Vertex_NUM][Max_Vertex_NUM]; typedef struct { typedef struct { VertexType vexs[MAX_VERTEX_NUM]; /*顶点向量*/ VertexData vexs[MAX_VERTEX_NUM];//顶点向量 AdjMatrix arcs; //邻接矩阵 ArcNode arcs ]; /*邻接矩阵*/ int vexnum, arcnum;//当前顶点数和弧数 int vexnum,arcnum; /*图的顶点数和弧数*/ GraphKind kind; GraphKindkind; //图种类标志/*图的种类标志*/ }Mgraph; } MGraph; /*(Adjacency Matrix Graph)*/
邻接表
当图中的边数较少时,相邻矩阵就会出现大量 的零元素,存储这些零元素将耗费大量的存储 空间.对于稀疏图,可以采用邻接表存储法. 邻接表(adjacency list)表示法是一种链式存储结 邻接表 链式存储结 构,由一个顺序存储的顶点表和n个链接存储 的边(弧)表组成.
邻接表存储结构
typedef struct ArcNode{ int adjvex; double weight; struct ArcNode *nextarc; }ArcNode; typedef struct { VertexType data; ArcNode *firstarc; }AdjList[MaxVnum]; typedef struct { int vexnum,arcnum; AdjList vertices; }AGraph;
有向图 G1
V2
V4
V4
无向图 G2
V5
完全图:n个顶点有n(n-1)/2条边的无向图 有向完全图: n个顶点有n(n-1)条弧的有向图
子图: G =(V,{E})和G1 = (V1,{E1}) 若V1属于V, E1属于E 则G1是G的子图
V1 V1 V1 V1 V2
V3
V3
V4
V3
V4
顶点v的度 顶点 的度 在无向图中与顶点v相关联的边的数目,记
0 ^ 1 ^
G2的邻接表 逆邻接表 逆邻接表: 求入度容易,求出度难
G1的逆邻接表
十字链表
将有向图的邻接表和逆邻接表结合起来得到的链 表. 在十字链表中,顶点结点存储数据元素,弧结点 存储弧及其上的信息.
十字链表实例
V0
V1
V2
<v0,v1> <v0,v2>
V3
0 v0 1 v1 2 v2 3 v3 ∧ 2 0 3 0∧
visited[v]=1; VisitFunc(v);//访问第v个顶点 for(w=FirstAdlVex(G,v);w;w=NextAdjVex(G,v,w)) if(!visited[w]) DFS(G,w);
}
算法分析
对于具有n个顶点和e条边的无向图或有向图,深度 优先周游算法对图中每顶点至多调用一次DFS函数 用相邻矩阵表示图时,共需检查n2个矩阵元素,所 需时间为O(n2) 用邻接表表示图时,找邻接点需将邻接表中所有边 结点检查一遍,需要时间O(e),对应的深度优先搜 索算法的时间复杂度为O(n+e)
为TD(v)
入度(ID(V)):有向图中指向某顶点的弧的数目 出度(OD(v)):有向图中从某顶点出发的弧的数目 有向图的度TD(v) = ID(V) + OD(v) 一个有n个顶点,e条边或弧的图,e和n有如下关 系:
路径(Path) 路径 回路或环( 回路或环(Cycle) ) 简单路径 顶点不重复的路径 两个顶点之间有路径 连通 连通图 任意两个顶点之间有路径 任意 连通分量 无向图中的极大连通子图. . 强连通图 有向图中,从v到v'和从v'到v都 有路径. 强连通分量 有向图中极大强连通子图.
7.2 图的存储结构
邻接矩阵 邻接表 十字链表(*) 邻接多重表(*)
邻接矩阵
用一个一维数组存储图中顶点的信息,用一个 二维数组(称为邻接矩阵)存储图中各顶点之 间的邻接关系. 假设图G=(V,E)有n个顶点,则邻接矩阵是一 个n×n的方阵,定义为:
1
arc[i][j]=
若(vi, vj)∈E(或<vi, vj>∈E) 其它
生成树(Spanning Tree): 极小连通子图,含有图 生成树 中全部顶点.但只有足以构成一棵树的n-1条边. 一棵有n个顶点的生成树有且仅有n-1条边.如果 它有n条边,则一定有环. 生成森林
7.1 7.2 7.3 7.4 7.5 7.6
基本概念和术语 图的存储结构 图的遍历 最小代价生成树 拓扑排序,关键路径 最短路径
有向图 若代表一条边的顶点序偶是有序的 (即边有方向),则称此图为有向图.
– 弧 在有向图里,这种有方向的边称之为弧,用 有序对< v,w >表示,称v为弧尾 弧尾(Tail),称w为弧 弧尾 头(Head)
若代表一条边的顶点序偶是无序的(即该边无方 向),则称此图为无向图 无向图. 无向图
V1 V2 V1 V3 V3
V1 从顶点v1出发进行DFS遍历 V2 V3 V1 V4 V5 V6 V7 V2 V8 V4 V8 V5 V6 V3
V7
int visited[MAX]; Statas (*VisitFunc)(int v); void DFSTraverse(Graph G,Status(*Visit)(int v)) {
边(弧)结点结构
顶点结构
图
邻接表图例
0 1 2 3 V1 V2 ^ V3 V4 2 3 ^ 0 ^ 1 ^ 0 1 2 3 4 V1 V2 V3 V4 V5 邻接表: 邻接表: 求出度容易,求入度难 3 1 ^
G1的邻接表 0 1 2 3 V1 V2 V3 V4 3 0 0 2 ^ ^ ^ ^
2 2