数据结构与算法图1
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
无向图的邻接矩阵总是对称的--可以采用压缩存储
网及其邻接矩阵
V1
3
V6 1
V5
5
V2
8
4
7
9
V3
6 5
5
V4
(a) 网
57 4 8 9 56 5 3 1
(b) 邻接矩阵
7.2.2 邻接表
--- 链式存储结构
#define MAX_VERTEX_NUM 20 typedef struct ArcNode{
7.3.1 深度优先搜索
12345678 visited 1 1 0 1 1 0 0 1
V1
V2
V4
V5
V3
V6
V7
V1 V2 V4 V8 V5
stack
V8
遍历顺序:
V1 V2 V4 V8 V5 V3 V6 V7
非连通的图重复上述过程, 使每个顶点均被访问
深度优先搜索算法
Boolean visited[MAX]; Status (* VisitFunc)(int v); void DFSTraverse(Graph G, Status (* visit)(int v)) { VisitFunc = visit;
第七章 图
图(Graph)是较线性表和树更为复杂的结构。 图中任意数据两个元素之间都可能相关。
G1 = (V1, { A1}) V1 = {v1,v2,v3,v4} A1 = {<v1,v2>,<v1,v3>,<v3,v4>,<v4,v1>}
G2 = (V2, { E2}) V2 = {v1,v2,v3,v4,v5} E2 = {(v1,v2),(v1,v4),(v2,v3),(v2,v5) ,(v3,v4),(v3,v5)}
} }
7.4 图的连通性问题
7.4.1 无向图的连通分量和生成树
V1
V2
V3
V1
V2
V3
V4
V6
V4
V5
V6
V7
V7
V8
V8
V5 深度优先生成树
广度优先生成树
7.4.3 最小生成树
连通网的生成树 一棵生成树的代价---树上各边的代价之和 最小生成树---- 一个连通网的所有生成树中 代价最小的生成树 求最小生成树的Prim算法 求最小生成树的Kruskal算法
int adjvex; struct ArcNode *nextarc;
表结点 Adjvex nextarc info
InfoType *info;
}ArcNode; typedef struct VNode{
Vetarc
ArcNode *firstarc;
for(v=0; v<G.vexnum; ++v) visited[v] = FALSE; for(v=0; v<G.vexnum; ++v)
if(!visited[v]) DFS(G,v); } void DFS(Graph G, int v) { visited[v] = TRUE; VisitFunc(v);
V1 V2 V3 V4 V5 V6 V7 V8
非连通的图重复上述过程, 使每个顶点均被访问
广度优先搜索算法
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)
} Vnode, AdjList [MAX_VERTEX_NUM ];
typedef struct {
AdjList verteces;
int
vexnum, arcnum;
int
kind;
}ALGraph;
邻接表的链式存储结构示意图
0 V1 1 V2 ^ 2 V3
3 V4
2
3^ 0^
G1的邻接表
0 V1
V1
2
V1
V2
4
V2
V3 7
V3
7.1 图的定义和基本术语(续二)
子图: G =(V,{E})和G1 = (V1,{E1}) 若V1属于V, E1属于E 则G1是G的子图
V1
V1
V1
V1
V2
V3
V3
V4
V3
V4
邻接点:无向图中有边相连的两个顶点互为邻接点 顶点的度:无向图中和某顶点相连的邻接点数 入度:有向图中指向某顶点的弧的数目 出度:有向图中从某顶点出发的弧的数目
VRType adj;
InfoType *info;
}ArcCell, AdjMatrix[MAX_VERTEX_NUM ][MAX_VERTEX_NUM ]
typedef struct {
VetexType vexs[MAX_VERTEX_NUM ];
AdjMatrix arc;
int
vexnum, arcnum;
GraphKind kind;
}MGraph;
数组表示法(邻接矩阵)
无向图、有向图、网均适用 易求各顶点的度。
例如有向图G1和无向图G2的邻接矩阵为
01 1 0
01010
G1.arc =
0 0
0 0
0 0
0 1
10101 G2.arc = 0 1 0 1 1
10 0 0
10100
01100
n2的存储量
7.1 图的定义和基本术语
有向图 G1
V1
V2
V3
V4
顶点 弧 弧尾 弧头
无向图 G2
V1
V2
V3
V4
V5
顶点 边
7.1 图的定义和基本术语(续一)
完全图:n个顶点有n(n-1)/2条边的无向图 有向完全图: n个顶点有n(n-1)条弧的有向图 稀疏图:有很少条边的图(如边数e < nlogn) 稠密图:非稀疏图 权: 与边或弧相关的数 网络: 带权的图
Prim算法示意图
6
V1 5 1
V2 5 V3 5 V4 36 42
V5 6 V6
V1
1
V2
V3
V4
V5
V6
V1
1
V2
V3
V4
4
V5
V6
V1
1
V2
V3
V4
42
V5
V6
V1
1
V2 5 V3
V4
42
V5
V6
V2 5
3 V5
V1
1
V3
V4
42
V6
Kruskal算法示意图
6
V1 5 1
V2 5 V3 5 V4 36 42
3^
1 V2
0^
2 V3
0^
3 V4
2^
G1的逆邻接表
1^
邻接表: 求出度容易,求入度难
0 V1
3
1^
1 V2
4
2
0^
2 V3
4
3
1^
3 V4
2
0^
4 V5
2
1^
G2的邻接表
邻接表: 求入度容易,求出度难
7.3 图的遍历
图的遍历:从图的某顶点出发,访问所 有顶点,且每个顶点仅被访问一次。 两种遍历图的路径: 深度优先搜索和广度优先搜索 它们对无向图和有向图都适用 深度优先搜索类似于树的先根遍历 广度优先搜索类似于树的层次遍历
不唯一,但n个顶点的生成树 有且仅有n-1条边。 生成森林:
7.2 图的存储结构 7.2.1 数组表示法
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20
typedef enum{DG, DN, AG, AN} GraphKind;
typedef struct ArcCell{
V5 6 V6
V1
1
V2
V3
V4
V5
V6
V1
1
V2
V3
V4
2
V5
V6
V1
1
V2
V3
V4
3
2
V5
V6
V2
3 V5
V1
1
V3
V4
42
V6
V2 5
3 V5
V1
1
V3
V4
42
V6
for(w=FirstAdjVex(G, v); w; w = NextAdjVex(G,v,w)) if(!visited[w]) DFS(G,w);
}
7.3.2 广度优先搜索
12345678 visited 1 0 0 0 0 0 0 0
V1
V2
V4
V5
V3
V6
V7
V2 V3
Queue
V8
遍历顺序:
7.1 图的定义和基本术语(续三)
路径:两个顶点之间的顶点序列,该序列的每个顶点
与其前驱是邻接点,每个顶点与其后继也是邻接点
回路(环):第一顶点和最后顶点相同的路径
简单路径: 顶点不重复的路径
连通:
两个顶点之间有路径
连通图: 任意两个顶点之间有路径
连通分量: 无向图中的极大连通子图。
强连通图:任意两个顶点之间有双向路径 强连通分量:有向图中的极大强连通子图。 连通图的生成树:极小连通子图。
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); } }