13. 0 1 2 3 4 5 6 7 8
Visited F F F F F T T T F
T T T T T F F F T
w2 Q
w1 w1 w2 w8 w7 w3 w5 w6 w4
V
V w3
w7 访问次序 :
w8
w4
w6
w5
14. void BFSTraverse(Graph G,
Status (*Visit)(int v)){
for (v=0; v<G.vexnum; ++v)
visited[v] = FALSE; // 初始化访问标
志
InitQueue(Q); // 置空的辅助队列 Q
for ( v=0; v<G.vexnum; ++v )
if … …
( !visited[v]) { // v 尚未访问
}
15. visited[u] = TRUE; Visit(u); // 访问 u
EnQueue(Q, v); // v 入队列
while (!QueueEmpty(Q)) {
DeQueue(Q, u);
// 队头元素出队并置为 u
for(w=FirstAdjVex(G, u); w!=0;
w=NextAdjVex(G,u,w))
if ( ! visited[w]) {
visited[w]=TRUE; Visit(w);
EnQueue(Q, w); // 访问的顶点 w 入队列
} // if
} // while
16. 图的连通性问题
连通分量 (Connected
A B
component)
当无向图为非连通图
C D E
时 , 从图中某一顶点出发
F G H
, 利用深度优先搜索算法
或广度优先搜索算法不 I K
J
可能遍历到图中的所有 M
L
顶点 , 只能访问到该顶点
所在的最大连通子图 ( 连
通分量 ) 的所有顶点。
17. A B A B
C D E C
F G H F
I K J
J M
L M L
若从无向图的每一
个连通分量中的一个 G H
顶点出发进行遍历 , D E
可求得无向图的所 I K
有连通分量。
25. 例如 :
a 19 b 5
14 12
7 c
18
e 8
16 3
g d
27 21
f 所得生成树权值和
= 14+8+3+5+16+21 = 67
26. 设置一个辅助数组,对每个顶
点,记录从顶点集 U 到 V - U 具有
代价最小的边:
adjvex lowcost
struct {
VertexType adjvex; // U 集中的顶点
VRType lowcost; // 边的权值
} closedge[MAX_VERTEX_NUM];
27. U: a
0 19 1
a b 5 2 V-U: b c d e f g
14 12 a b c d e f g
7 c a
18 0 19 ∞ ∞ 14 ∞ 18
16
4 e 8 3 b 19 0 5 7 12 ∞ ∞
d
6 g 27 21 3
c ∞ 5 0 3 ∞ ∞ ∞
d ∞ 7 3 0 8 21 ∞
5
f e 14 12 ∞ 8 0 ∞ 16
f ∞ ∞ ∞ 21 ∞ 0 27
g 18 ∞ ∞ ∞ 16 27 0
0 1 2 3 4 5 6
closedge
Adjvex cd
e
a d e a d a
e
Lowcost 19
12
5
7 3 8 14 18
21 16
28. void MiniSpanTree_P(MGraph G, VertexType u) {
// 用普里姆算法从顶点 u 出发构造网 G 的最小生成
树
k = LocateVex ( G, u ); // 定位 u 的位置 k
for ( j=0; j<G.vexnum; ++j ) // 辅助数组初始化
if (j!=k)
closedge[j] = { u, G.arcs[k][j].adj };
closedge[k].lowcost = 0; // 初始, U = {u}
for (i=0; i<G.vexnum; ++i) {
继续向生成树上添加顶点 ;
}
} //MiniSpanTree
29. k = minimum(closedge); // 求出加入生成树的下一个
顶点 ( k )
printf(closedge[k].adjvex, G.vexs[k]);
// 输出生成树上一条边
closedge[k].lowcost = 0; // 第 k 顶点并入 U 集
for (j=0; j<G.vexnum; ++j)
// 修改其它顶点的最小边
if (G.arcs[k][j].adj < closedge[j].lowcost)
closedge[j] = { G.vexs[k], G.arcs[k][j].adj };
// 新顶点并入 U 后重新选择最小边
41. c
a d
g e
b f
h
a b h c d g f e
在算法中需要用定量的描述替代定性的概念
没有前驱的顶点 点 入度为零的顶点
删除顶点及以它为尾的弧 弧 弧头顶点的入度减
42. c a 2 6 ∧
0
a d 1 b 6 7 ∧
g e 2 c 3 ∧
3 d 4 6 ∧
b f
h 4 e ∧
5 f 4 ∧
s 6 g 5 ∧
7 h 5 ∧
h
b 0 1 2 3 4 5 6 7
a
c
d indegree 0 0 0 1 2 2 3 1
1 0 0 1 2 0
0 1
0
输出次序 : b h a c d g f e
43. 算法的设计与实现
l 采用邻接表作有向图的存储结构
l 增加一个存放入度的数组 (indegree), 记
录拓扑排序过程中 , 顶点入度的变化 .
l 入度 = 0 的顶点为没有前驱的顶点
l 删除顶点及其尾弧的操作可换以弧头
顶点的入度 -1 来实现 .
l 设置堆栈存储入度为 0 的顶点 , 按照后
进先出的策略输出拓扑序列
44. 算法描述 : 若 G 无回路 , 则输出 G 的顶点的
一个拓扑序列并返回 OK. 否则返回 ERROR.
Status Topologicalsort(ALGraph G) {
FindinDegree(G,indegree); // 对各顶点求入度
InitStack(s); // 初始化 0 入度顶点栈
Count=0; // 已输出的顶点数 , 初值为 0
// 对所有顶点 i, 若入度之和为 0, 则将 i 入零入度顶点
栈 S.
For(i=0;i<G.vexnum;++i)
if(!indegree[i]) push(s,i);