数据结构与算法第六章08

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
v0 v3 v2 v4 (a) 无向图G1 v2 (b) 有向图G2 v3 v1 v0 v1
v0 v3 v2 v4 v2 v3 v1 v0 v1
(a) 无向图G1的生成树
(b) 有向图G2的生成树
图7.2 图的示例
v0 v1
图7.7
v2 v3
图7.2中无向图和有向图的生成树示例
v0 v1 v5 v2
B
C
D
E
A
B C D E
C D E
0 0 0 1 0
1 0 0 1 0
0 1 0 0 1
0 0 1 0 0
1 0 0 0 0


在有向图中, 统计第 i 行 1 的个数可得顶点 i 的出度,统计第 j 列 1 的个数可得顶点 j 的入度。 在无向图中, 统计第 i 行 (列) 1 的个数可得 顶点i 的度。
//添加一条边 bool setEdge(int fromVertex,int toVertex,int weight); //删一条边 bool delEdge(int fromVertex,int toVertex);
//如果oneEdge是边则返回TRUE,否则返回FALSE
bool IsEdge(Edge oneEdge); //返回边oneEdge的始点 int FromVertex(Edge oneEdge); //返回边oneEdge的终点 int ToVertex(Edge oneEdge); //返回边oneEdge的权 int Weight(Edge oneEdge); };
~Graph() { delete [] Mark; delete [] Indegree; }
// 析构函数 // 释放Mark数组 // 释放Indegree数组
int VerticesNum() { // 返回图中顶点的个数 return numVertex; } bool IsEdge(Edge oneEdge) {// oneEdge是否是边 if (oneEdge.weight > 0 && oneEdge.weight < INFINITY && oneEdge.to >= 0) return true; else return false; } virtual Edge FirstEdge(int oneVertex)=0; virtual Edge NextEdge(Edge preEdge)=0; int FromVertex(Edge oneEdge) {return oneEdge.from;} int ToVertex(Edge oneEdge) { return oneEdge.to;} int Weight(Edge oneEdge) { return oneEdge.weight;} virtual void setEdge(int fromVertex,int toVertex,int weight)=0; virtual void delEdge(int fromVertex,int toVertex)=0; };
假设图中有 n 个顶点,e 条边,则
含有 e=n(n-1)/2 条边的无向图称作 完全图; 含有 e=n(n-1) 条弧的有向图称作 有向完全图; 若边或弧的个数 e<nlogn,则称作 稀疏图,否则称作稠密图。

稀疏图如G7。稠密图,如G8。
V1 V4 V5
V2 V3 V6 V2
V1
V3
V7 V8 V9 V10 V11 G7 V4 G8
网络的邻接矩阵
W(i , j ), 若i j且 i, j E或(i, j ) E A.arcs i ][ j ] 0, [ 若i j且 i, j E或(i, j ) E 0, 若i j
2 3 9 4
8 6 5
3 2
0
1
1
0 0 A.arcs 3 0
v3
v4
v5
v4
(a)有向图
(b)有向图的生成森林来自图7.9 有向图及其生成森林
6.2 图的抽象数据类型 基本操作
结构的建立和销毁
对顶点的访问操作
插入或删除顶点
插入和删除弧
对邻接点的操作 遍历
class Graph{ //图的ADT public: int VerticesNum(); //返回图的顶点个数 int EdgesNum(); //返回图的边数 //返回与顶点oneVertex相关联的第一条边 Edge FirstEdge(int oneVertex); //返回与边PreEdge有相同关联顶点 // oneVertex的下一条边 Edge NextEdge(Edge preEdge);
C
D B A E C
设图G=(V,{VR}) 和 图 G=(V,{VR}), B 且 VV, VRVR, 则称 G 为 G 的子图。
D
v0 v3 v2
v1
v0
v1
v4 (a) 无向图G1
v2 (b) 有向图G2
v3
v0 v0 v2 v3
v1
v0
v0
v1
v4
v3 v2 v3
(b)有向图 G2的若干子图 (a)无向图 G1的若干子图 图7.4 图7.2的若干子图


顶点 图中数据元素如V1
V1
弧 若有序顶点<v,w> E, V2 V3 <v,w>表示一条弧,如<v5,v6> 弧头 w为弧头,如v6 弧尾 v为弧尾 ,如v5 V4 G1 有向图 在有向图中,顶点对 <v, w> 是有序的,既由顶点集和弧集构成的图。如G2 V5 边 无序顶点(x,y)E,(x,y)表示一条边, 如(v1,v3) V6 V7 无向图 在无向图中,顶点对(x,y)是 无序的,既顶点集和边集构成的图。如G1
假设一个连通图有 n 个顶点和 e 条边, 其中 n-1 条边和 n 个顶点构成一个极小 连通子图,称该极小连通子图为此连通图 的生成树。 B A F E C D
对非连通图,则 称由各个连通分 量的生成树的集 合为此非连通图 的生成森林。
如果无向图G的一个生成树 G′上添加一条边, 则G′中一定有环,因为依附于这条边的两个顶 点有另一条路径。相反,如果G′的边数小于n-1, 则G′一定不连通。
边类from是边的始点to是终点weight是边的权缺省构造函数给定参数的构造函数图中顶点的个数图中顶点的个数图中边的条数标记图的顶点是否被访问过存放图中顶点的入度图的构造函数标志位设为unvisited入度设为0graphdeletemark
任课教师:贺怀清 电话:24092482 计算机科学与技术学院
1 0 5 0
0 9 0 6
4 2 8 0
【代码7.2】 图的基类 class Edge { // 边类 public: int from, to, weight; // from是边的始点,to是终点,weight是边的权 Edge() { // 缺省构造函数 from = -1; to = -1; weight = 0; } Edge(int f,int t,int w) { // 给定参数的构造函数 from = f; to = t; weight = w; } }; class Graph { public: int numVertex; // 图中顶点的个数 int numEdge; // 图中边的条数 int *Mark; // 标记图的顶点是否被访问过 int *Indegree; // 存放图中顶点的入度 Graph(int numVert) // 图的构造函数 {numVertex = numVert; numEdge = 0; Indegree = new int[numVertex]; Mark = new int[numVertex]; for (int i = 0; i < numVertex; i++) { Mark[i] = UNVISITED; // 标志位设为UNVISITED Indegree[i] = 0; // 入度设为0 } }
6.3 图的存储结构
6.3.1 图的相邻矩阵(adjacency matrix)表示法 6.3.2 图的邻接表(adjacency list)表 示法
6.3.1 图的相邻矩阵(adjacency matrix)表示法
相邻矩阵 表示顶点间相邻关系的矩阵。 若G是一个具有n个顶点的图,则G的 相邻矩阵是如下定义的n×n矩阵: A[i,j]=1,若(Vi,Vj)(或<Vi,Vj>)是图 G的边; A[i,j]=0,若(Vi,Vj)(或<Vi,Vj>)不是 图G的边。 相邻矩阵的空间代价为Θ (n2)
对有向图, 若任意两个顶点之间都存在
一条有向路径,则称此有向图为强连通图。 否则,其各个强连通子图称作它的 A 强连通分量。 A B E B A
C
D
C D
E
C
D
有根的图 一个有向图中,若存在一个顶点V0,从此 顶点有路径可以到达图中其它所有顶点, 则称此有向图为有根的图,V0称作图的 根。 自由树(free tree) 不带有简单回路的无向图,它是连通的, 并且具有|V|-1条边
6.1 图的基本概念
6.2 图的抽象数据类型
6.3 图的存储结构
6.4 图的周游(深度、广度、拓扑) 6.5 最短路径问题
6.6 最小支撑树
6.1 图的基本概念
图的结构定义:图是由一个顶点集 V 和一
个弧集 VR构成的数据结构。 Graph = (V, VR ) 其中,VR={<v,w>| v,w∈V 且 P(v,w)} <v,w>表示从 v 到 w 的一条弧,并称 v为 弧尾(始点),w为弧头(终点)。 谓词 P(v,w) 定义了弧 <v,w>的意义或信息。
(B, E), (B, F), (C, D), (C, F) ,(D, F)}
B
C D
F
E
名词和术语
网、子图
完全图、稀疏图、稠密图
邻接点、度、入度、出度 路径、路径长度、简单路径、简单回路
连通图、连通分量、 强连通图、强连通分量 生成树、生成森林
15
A
21
2
9 11
弧或边带权的图
B
3
7
E
分别称作有向网或 无向网。
A
A
B
A
A
B
B
C
C
D
B
C
C
D
(a)无向完全图
(b)有向完全图
图7.3 完全图
假若顶点v 和顶点w 之间存在一条边, 则称顶点v 和w 互为邻接点,
边(v,w) 和顶点v 和w 相关联。 和顶点v 关联的边的数目定义为边的度。
例如: 右侧图中
ID(B) = 3 ID(A) = 2
B
C
A F E
D
对有向图来说,由于弧有方向性,则
[代码7.3] 用相邻矩阵表示图 class Graphm: public Graph { private: int **matrix; // 指向相邻矩阵的指针 public: Graphm(int numVert):Graph(numVert) // 构造函数 { int i,j; // i, j作为for循环中的计数器 matrix = (int**)new int*[numVertex]; // 申请matrix数组行向量数组 for (i = 0;i < numVertex;i++) // 申请matrix数组行的存储空间 matrix[i] = new int[numVertex]; for (i = 0;i < numVertex;i++) // 相邻矩阵的所有元素都初始化为0 for (j = 0;j < numVertex;j++) matrix[i][j] = 0; }
V8 G2
例如: G1 = (V1, VR1)
A B E 其中 V1={A, B, C, D, E} VR1={<A,B>, <A,E>,
<B,C>, <C,D>, <D,B>, <D,A>, <E,C> }
C
D
例如: G2=(V2,VR2) V2={A, B, C, D, E, F} A VR2={(A, B), (A, E),
C D
个顶点相同的路径。
不带回路的图称为无环图(acyclic graph).
不带回路的有向图称为有向无环图 (directed acyclic graph,简记为DAG)
若图G中任意两个顶 点之间都有路径相通, 则称此图为连通图; A B A
F E
B
C D
C
D
F
E
若无向图为非连通图, 则图中每一个连通部 分称作此图的连通分 量。
A
有入度和出度之分
B
C D
E
例如: OD(B) = 1 ID(B) = 2
顶点的出度: 以顶点 v 为弧尾的弧的数目; 顶点的入度: 以顶点 v为弧头的弧的数目。 顶点的度(TD)= 出度(OD)+入度(ID)
TD(B) = 3
设图G=(V,{VR})中的一个顶点序列 { u=vi,0,vi,1, …, vi,m=w}中,(vi,j-1,vi,j)VR 1≤j≤m, 则称从顶点u 到顶点w 之间存在一条路径。 路径上边的数目称作路径长度。 如:从A到D长度为 3 简单路径:指序列中顶 的路径{A,B,C,D} 点不重复出现的路径。 A 简单回路:指序列中 B E 第一个顶点和最后一
定义:矩阵的元素为
Aij=
A
{ 1 (i,j)VR
B C D E F
0 (i,j)VR
B A F
C D E
A
B
C D E F
0 1 0 0 1 0
1 0 0 0 1 1
0 0 0 1 0 1
0 0 1 0 0 1
1 1 0 0 0 0
0 0 1 1 0 0
有向图的邻接矩阵 为非对称矩阵
A
B
A
相关文档
最新文档