《数据结构》习题汇编07 第七章 图 试题

更新时间:2024-04-15 04:43:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第七章 图 试题

一、单项选择题

1. 在无向图中定义顶点的度为与它相关联的( )的数目。

A. 顶点 B. 边 C. 权 D. 权值

2. 在无向图中定义顶点 vi与vj之间的路径为从vi到达vj的一个( )。

A. 顶点序列 B. 边序列 C. 权值总和 D. 边的条数

3. 图的简单路径是指( )不重复的路径。

A. 权值 B. 顶点 C. 边

D. 边与顶点均

4. 设无向图的顶点个数为n,则该图最多有( )条边。

A. n-1 B. n(n-1)/2 C. n(n+1)/2 5. n个顶点的连通图至少有( )条边。

A. n-1 B. n

C. n+1

D. n(n-1)

D. 0

6. 在一个无向图中,所有顶点的度数之和等于所有边数的 ( ) 倍。

A. 3 B. 2 C. 1 D. 1/2 7. 若采用邻接矩阵法存储一个n个顶点的无向图,则该邻接矩阵是一个 ( )。

A. 上三角矩阵 B. 稀疏矩阵 C. 对角矩阵 D. 对称矩阵

8. 图的深度优先搜索类似于树的( )次序遍历。

A. 先根 B. 中根 C. 后根 9. 图的广度优先搜索类似于树的( )次序遍历。

A. 先根 B. 中根 C. 后根

D. 层次

D. 层次

10. 在用Kruskal算法求解带权连通图的最小(代价)生成树时,通常采用一个( )辅助结构,

判断一条边的两个端点是否在同一个连通分量上。

A. 位向量 B. 堆 C. 并查集 D. 生成树顶点集合 11. 在用Kruskal算法求解带权连通图的最小(代价)生成树时,选择权值最小的边的原则是该边不能

在图中构成( )。

A. 重边 B. 有向环 C. 回路 D. 权值重复的边

12. 在用Dijkstra算法求解带权有向图的最短路径问题时,要求图中每条边所带的权值必须是

( )。

A. 非零 B. 非整 C. 非负 D. 非正

13. 在一个连通图中进行深度优先搜索得到一棵深度优先生成树,树根结点是关节点的充要条件是它至少

有( )子女。

1

A. 1

B. 2 C. 3 D. 0

14. 设有向图有n个顶点和e条边,采用邻接表作为其存储表示,在进行拓扑排序时,总的计算时间为

( )。

A. O(nlog2e) B. O(n+e) C. O(ne) D. O(n2)

15. 设有向图有n个顶点和e条边,采用邻接矩阵作为其存储表示,在进行拓扑排序时,总的计算时间为

( )。

A. O(nlog2e) B. O(n+e) C. O(ne) D. O(n2)

16. 设G1 = (V1, E1) 和G2 = (V2, E2) 为两个图,如果V1 ? V2,E1 ? E2,则称( A. G1是G2的子图 B. G2是G1的子图

C. G1是G2的连通分量 D. G2是G1的连通分量 17. 有向图的一个顶点的度为该顶点的( )。 A. 入度 B. 出度

C. 入度与出度之和 D. (入度﹢出度))/2

18. 一个连通图的生成树是包含图中所有顶点的一个( )子图。 A. 极小 B. 连通 C. 极小连通 D. 无环

19. n (n>1) 个顶点的强连通图中至少含有( )条有向边。 A. n-1 B. n n(n-1)/2 D. n(n-1)

20. 在一个带权连通图G中,权值最小的边一定包含在G的( )生成树中。 A. 某个最小 B. 任何最小 C. 广度优先 D.深度优先

21. 对于具有e条边的无向图,它的邻接表中有( )个边结点。 A. e-1 B. e C. 2(e-1) D. 2e

22. 对于如图所示的带权有向图,从顶点1到顶点5的最短路径为( )。 A.1, 4, 5 B. 1, 2, 3, 5 C. 1, 4, 3, 5 D. 1, 2, 4, 3, 5 1 4

69

2 3 1 5 85

2 3 23. 具有n个顶点的有向无环图最多可包含( )条有向边。 A. n-1 B. n C. n(n-1)/2 D.n(n-1)

24. 一个有n个顶点和n条边的无向图一定是( )。

A. 连通的 B. 不连通的 C. 无环的 D. 有环的

25. 在n个顶点的有向无环图的邻接矩阵中至少有( )个零元素。 A. n B. n(n-1)/2 C. n(n+1)/2 D. n(n-1)

。 2

)26. 对于有向图,其邻接矩阵表示比邻接表表示更易于( )。 A. 求一个顶点的度 B. 求一个顶点的邻接点 C. 进行图的深度优先遍历 D. 进行图的广度优先遍历

27. 在一个有向图的邻接矩阵表示中,删除一条边需要耗费的时间是( )。 A. O(1) B. O(i) C. O(j) D. O(i+j)

28. 与邻接矩阵相比,邻接表更适合于存储( )图。 A. 无向 B.连通 C.稀疏

D. 稠密图

29. 设一个有n个顶点和e条边的有向图采用邻接矩阵表示,要计算某个顶点的出度所耗费的时间是

( )。

A. O(n) B. O(e) C. O(n+e) D. O(n2)

30. 为了实现图的广度优先遍历,BFS算法使用的一个辅助数据结构是( )。 A. 栈 B. 队列 C. 二叉树 D. 树

参考答案: 1. B

6. B 11.C 16. A 21. D 26. A

2. A 7. D 12. C 17. C 22. D 27. A

3. B 8. A 13. B 14. B 18. C 19. B 23. C 24. D 28. C 29. A

4. B 9. D 15. D 20. A 25. C 30. B

5. A 10. C

二、填空题

1. 图的定义包含一个顶点集合和一个边集合。其中,顶点集合是一个有穷________集合。

2. 用邻接矩阵存储图,占用存储空间数与图中顶点个数________关,与边数________关。

3. n (n﹥0) 个顶点的无向图最多有________条边,最少有________条边。

4. n (n﹥0) 个顶点的连通无向图最少有________条边。

?010??100????010??,则图G一定是________向图。 5. 若3个顶点的图G的邻接矩阵为?

6. n (n﹥0) 个顶点的连通无向图各顶点的度之和最少为________。

7. 设图G = (V, E),V = {V0, V1, V2, V3}, E = {(V0, V1), (V0, V2), (V0, V3), (V1,

V3)},则从顶点V0开始的图G的不同深度优先序列有________种,例如______________。

8. 设图G = (V, E),V = {P, Q, R, S, T}, E = {, , , },

3

从顶点P出发,对图G进行广度优先搜索所得的所有序列为__________和___________。

9. n (n﹥0) 个顶点的无向图中顶点的度的最大值为________。

10. 在重连通图中每个顶点的度至少为________。

11. 在非重连通图中进行深度优先搜索,则深度优先生成树的根为关节点的充要条件是它至少有

________个子女。

12. (n﹥0) 个顶点的连通无向图的生成树至少有________条边。

13. 101个顶点的连通网络N有100条边,其中权值为1, 2, 3, 4, 5, 6, 7, 8, 9, 10的边各

10条,则网络N的最小生成树各边的权值之和为_________。

14. 在使用Kruskal算法构造连通网络的最小生成树时,只有当一条候选边的两个端点不在同一个

________上,才有可能加入到生成树中。

15. 深度优先生成树的高度比广度优先生成树的高度________。

16. 求解带权连通图最小生成树的Prim算法适合于________图的情形,而Kruskal算法适合于

________图的情形。

17. 求解最短路径的Dijkstra算法适用于各边上的权值________的情形。若设图的顶点数为n,则该

算法的时间复杂度为________。

18. 若对一个有向无环图进行拓扑排序,再对排在拓扑有序序列中的所有顶点按其先后次序重新编号,则

在相应的邻接矩阵中所有________元素将集中到对角线以上。

参考答案: 1. 非空 2. 有, 无 3. n(n-1)/2, 0

4. n-1 5. 有 6. 2(n-1)

7. 4,V0V1V3V2(或V0V2V1V3, V0V2V3V1, V0V3V1V2) 8. PQRST和PRQTS 9. n-1 10. 2

11. 2 12. n-1 13. 550

14. 连通分量 17. 非负,O(n2)

15. 高 16. 稠密,稀疏 18. 非零(或值为1的)

三、判断题

1. 一个图的子图可以是空图,顶点个数为0。

2. 存储图的邻接矩阵中,矩阵元素个数不但与图的顶点个数有关,而且与图的边数也有关。

3. 一个有1000个顶点和1000条边的有向图的邻接矩阵是一个稀疏矩阵。

4. 对一个连通图进行一次深度优先搜索(depth first search)可以遍访图中的所有顶点。

4

5. 有n (n≥1) 个顶点的无向连通图最少有n-1条边。

6. 有n (n≥1) 个顶点的有向强连通图最少有n条边。

7. 图中各个顶点的编号是人为的,不是它本身固有的,因此可以因为某种需要改变顶点的编号。

8. 如果无向图中各个顶点的度都大于2,则该图中必有回路。

9. 如果有向图中各个顶点的度都大于2,则该图中必有回路。

10. 图的深度优先搜索(depth first search)是一种典型的回溯搜索的例子,可以通过递归算法求

解。

11. 图的广度优先搜索(breadth first search)算法不是递归算法。

12. 有n个顶点、e条边的带权有向图的最小生成树一般由n个顶点和n-1条边组成。

13. 对于一个边上权值任意的带权有向图,使用Dijkstra算法可以求一个顶点到其它各个顶点的最短路

径。

14. 对一个有向图进行拓扑排序(topological sorting),一定可以将图的所有顶点按其关键码大小

排列到一个拓扑有序的序列中。

15. 有回路的有向图不能完成拓扑排序。

16. 对任何用顶点表示活动的网络(AOV网)进行拓扑排序的结果都是唯一的。

17. 用边表示活动的网络(AOE网)的关键路径是指从源点到终点的路径长度最长的路径。

18. 对于AOE网络,加速任一关键活动就能使整个工程提前完成。

19. 对于AOE网络,任一关键活动延迟将导致整个工程延迟完成。

20. 在AOE网络中,可能同时存在几条关键路径,称所有关键路径都需通过的有向边为桥。如果加速这样

的桥上的关键活动就能使整个工程提前完成。

21. 用邻接矩阵存储一个图时,在不考虑压缩存储的情况下,所占用的存储空间大小只与图中的顶点个数

有关,而与图的边数无关。

22. 邻接表只能用于有向图的存储,邻接矩阵对于有向图和无向图的存储都适用。

23. 邻接矩阵只适用于稠密图(边数接近于顶点数的平方),邻接表适用于稀疏图(边数远小于顶点数的平

方)

24. 存储无向图的邻接矩阵是对称的,因此只要存储邻接矩阵的下(上)三角部分就可以了。

5

5. 以顶点 ① 为根的深度优先生成树(不唯一):

② ③ ② ③ ④ ⑤

④ ⑤

以顶点 ② 为根的广度优先生成树: ① ② ③

6. 深度优先生成森林为: V0 VV3

2 V1

V4 V5 V6 V7

广度优先生成森林为: V0 VV3

2 V1 V4 V5 V6 V7

7. 当图中的顶点个数等于边的条数时,ADJ = INC*INCT-I成立。

图G对应的邻接矩阵为:

01234567??01100000?0?10011000?1?10000110??2ADJ???01000001???3?01000001?4?00100001???5?00100001?6??00011110???7

11

对应的关联矩阵为:

0123456789??1100000000?0?1011000000?1?100110000??2INC??0?0010001000???3?0001000100?4?0000100010???5?0000010001?6??0000001111???7

8. 应用Kruskal算法顺序选出最小生成树的各条边为: ( 始顶点号,终顶点号, 权值 ) 0 ( 0, 3, 1 )

( 2, 5, 2 )

1 1 2 ( 1, 4, 3 )

( 3, 5, 4 )

3 5 3 4 2 ( 3, 4, 5 ) 4 5

9. 采用prim算法从顶点0开始构造最小生成树的过程:

S顶点号 Edge(顶点,顶点,权值) : : 0 ( 0, 1, 9 ) 0, 1 ( 1, 3, 5 ) 0, 1, 3 ( 1, 2, 7 ) 0, 1, 3, 2 ( 2, 4, 6 ) 0, 1, 3, 2, 4 ( 2, 5, 7 ) 0, 1, 3, 2, 4, 5 9 0 1 7 5 2 6 7 3 4 5

10. 最小生成树及其邻接矩阵如图所示

① 16

② ??016??1421?

5

?16059?19??? 14

11

Edge???506??? ????601811?? ⑤

④ 6

?14???026??

????11?0???选 择 的 边

去 掉 的 边 (顶点, 顶权值) (顶点, 顶权值)

点, 点,

12

( 2 ,

16 ) ( , , ) 1 ,

( 5 ,

14 ) ( , , ) 1 ,

( 6 ,

21 ) ( , , ) 1 ,

( 6 ,

19 ) ( 6 , 1 , 21 ) 2 ,

( 6 ,

11 ) ( , , ) 4 ,

( 6 ,

26 ) ( 6 , 5 , 26 ) 5 ,

( 5 ,

18 ) ( 6 , 2 , 19 ) 4 ,

( 4 ,

9 ) ( 5 , 4 , 18 ) 2 ,

( 3 ,

5 ) ( , , ) 2 ,

( 4 ,

6 ) ( 4 , 2 , 9 )

3 ,

选择顺序不唯一。

相应的AOV网络为:

A1 A4 A0 A2 A5 A7

A3 A6 一个拓扑排序序列为:A0,A1,A4,A2,A5,A3,A6,A7。 注意:拓扑排序结果不唯一。按拓扑有序的次序对所有顶点从新编号:

原编号 A0 A1 A4 A2 A5 A3 A6 A7 新编号 A0 A1 A2 A3 A4 A5 A6 A7 A1 A2 A0 A3 A4 A7

A5 A6 相应邻接矩阵为:

13

11.

0?0?0??0?Edge??0?0??0?0???011000000020100000031000000040011000051001000060000010070?0??0??0?1??0?1??0??01234567

12. 针对下图所示的AOE网络

2 2

1

4

15 11 3

10 19 5 5 4 6 6 各顶点(事件)的最早可能开始时间Ve(i)和最迟允许开始时间Vl(i)参看下表: 顶点 Ve Vl

各边(活动)的最早可能开始时间Ee(k)和最迟允许开始时间El(k)参看下表: 边 <1,2> <1,3> <3,2> <2,5> <3,5> <2,4> <4,6> <5,6> Ee 0 0 15 19 15 19 29 38 El 17 0 15 19 27 27 37 38

如果活动k的最早可能开始时间Ee(k) 与最迟允许开始时间El(k)相等,则该活动是关键活动。本题的关键活动为<1,3>, <3,2>, <2,5>, <5,6>,它们组成关键路径。这些关键活动中任一个提前完成,整个工程就能提前完成。

整个工程最早在43天完成。由关键活动组成的AOV网络如图所示。 10 2 4 2 6

1 19 6 4 15 11 5 5 3

13. 带权有向图如图所示: 0

7

3

8 1 4 1 2 9 5 2 4 4 1 0 0 2 19 19 3 15 15 4 29 37 5 38 38 6 43 43

14

应用Dijkstra算法求从顶点V0到其他各顶点的最短路径Path和最短路径长度Len的步骤如下:

步V0 V1 V2 V3 V4 动作 骤 Path LPath LPath LPath L en en en en 1 V0V1 4 — ∞ V0V3 7 — ∞ 选V0V1 V0V1 4 V0V1V2 8 V0V3 7 — ∞ 参照V1调整 2 V0V1 4 V0V1V2 8 V0V3 7 — ∞ 选V0V3 V0V1 4 V0V1V2 8 V0V3 7 V0V3V4 12 参照V3调整 3 V0V1 4 V0V1V2 8 V0V3 7 V0V3V4 12 选V0V1V2 V0V1 4 V0V1V2 8 V0V3 7 V0V1V2V4 10 参照V2调整 4 V0V1 4 V0V1V2 8 V0V3 7 V0V1V2V4 10 选V0V1V2V4

14. 图G为 p2

p1 p3 p6

p4 p5 可能的施工顺序有:

p1, p2, p4, p3, p5, p6 p1, p4, p2, p3, p5, p6 p4, p5, p1, p3, p2, p6

15. 该图的强连通分量分别为:

a

d

b c

f g

e

五、算法分析题

1. 已知有向图的邻接矩阵表示及其一个算法描述如下: 0 1 1 1 1 0 0 1 0 0

A = 0 0 0 1 1 1 1 0 0 0

0 0 1 1 0

15

const int MaxVertices = 5;

struct Graph { //图的邻接矩阵表示 int Edge[MaxVertices][MaxVertices]; //有向图邻接距阵 int CurrentNode; //有向图当前结点数 int CurrentEdges; //当前边数 }

int unknown ( int i ) {

int d = 0;

for ( int j = 0; j < CurrentNode; j++) { if ( Edge[i][j] != 0 ) d++;

if ( Edge[j][i] != 0 ) d++; }

return d; }

(1) 若定义图的一个对象Graph G,则执行操作G.unknown (3) 后的返回值是多少? (2) 试说明该算法的功能及时间复杂度。

2. 已知有向图的邻接矩阵表示及其一个操作算法描述如下:

0 1 1 0 1 0 0 0 0 0 A = 0 0 0 1 1

1 1 0 0 0

0 0 0 1 0

const int MaxVertices = 5;

struct Graph { //图的邻接矩阵表示 int Edge[MaxVertices][MaxVertices]; //有向图邻接距阵 int CurrentNode; //有向图当前结点数 int CurrentEdges; //当前边数 }

void unknown ( int i ) { int d, j; d = 0;

for ( j = 0; j < CurrentNode; j++ ) {

if ( Edge[i][j] ) { d++; Edge[i][j] = 0; } if ( Edge[j][i] ) { d++; Edge[j][i] = 0; } }

CurrentEdges -= d; }

若定义图的一个对象Graph G,试写出执行操作G.unknown (3) 后该图的邻接矩阵,并说明该算法的功能。

3. 已知有向图的邻接表类的表示的形式描述如下:

16

struct Edge { //邻接表中边结点的定义 int dest; //邻接的结点 float cost; //边的权值

Edge * link; };

template struct Vertex { //邻接表中顶点的定义 Type data;

Edge *adj; };

template struct Graph { //邻接表 Vertex * NodeTable; //顶点表

int NumVertices; //当前顶点个数 int NumEdges; //当前边数

int Degree[MaxVertices]; //各个顶点的度的记录数组

}

//下列算法是计算有向图中各个顶点的度,并保存在数组Degree[ ]中。请在 //填入合适的内容,使其成为一个完整的算法。

void FindDegree ( ) {

int i; Edge * p = NULL;

for ( i = 0; i < NumVertices; i++ ) Degree[i] = (1) ; for ( i = 0; i < NumVertices; i++)

for ( p = NodeTable[i].adj; p != NULL; p = p->link ) { (2) ; (3) ; }

};

4. 已知有向图的邻接表类的表示的形式描述如下:

struct Edge { //邻接表中边结点的定义

int dest; //邻接的结点 float cost; //边的权值 Edge * link;

}; template struct Vertex { //邻接表中顶点的定义 Type data;

Edge *adj; };

template struct Graph { //邻接表 Vertex * NodeTable; //顶点表

int NumVertices; //当前顶点个数 int NumEdges; //当前边数

int Degree[MaxVertices]; //各个顶点的度的记录数组

}

17

//下列算法是计算有向图G中一个顶点vi的入度。请在 处填入合适的内容, //使其成为一个完整的算法。

void FindDegree ( int i ) {

int deg, j; Edge * p = NULL;

deg = 0;

for ( j = 0; j < NumVertices; j++ ) {

p = NodeTable[j].adj;

while ( (1) ) { p = p->link;

if ( p == NULL ) break; }

if ( p != NULL ) (2) ;

} return deg; }

5. 已知有向图的邻接表类的表示的形式描述如下:

struct Edge { //邻接表中边结点的定义

int dest; //邻接的结点 float cost; //边的权值 Edge * link;

}; template struct Vertex { //邻接表中顶点的定义 Type data;

Edge *adj; };

template struct Graph { //邻接表 Vertex * NodeTable; //顶点表

int NumVertices; //当前顶点个数 int NumEdges; //当前边数

int Degree[MaxVertices]; //各个顶点的度的记录数组

}

//下列算法是从有向图G中删除所有以vi为弧头的有向边。请在 处填入合适 //的内容,使其成为一个完整的算法。

void DeletEdge ( int i ) {

int de = 0, j; Edge *p, *q;

if ( i >= NumVertices )

{ cout << \错误输入\ for ( j = 0; j < NumVertices; j++ ) {

p = NodeTable[j].adj;

while ( (1) ) { q = p; p = p->link; } if ( p != NULL ) {

if ( p != NodeTable[j].adj ) q->link = p->link;

else (2) ;

18

delete p; de++; } }

NumEdges = NumEdges - de;

}

6. 已知带权图的邻接矩阵表示和邻接表类表示的形式描述分别如下:

(1) 邻接矩阵的定义

#define INFINITY INT_MAX //INT_MAX为最大整数,表示∞ const int MaxVertices = 20;

template struct AdjMatrix { Type * NodeTable; //顶点表定义 float arr[Maxvertices][MaxVertices]; //邻接矩阵定义

int NumVertices; //当前顶点个数 int NumEdges; //当前边数

}; (2) 邻接表定义

struct Edge { //邻接表中边结点的定义 int dest; //邻接的结点 float cost;

//边的权值

Edge * link;

}; template struct Vertex { //邻接表中顶点的定义

Type data;

Edge *adj; };

template struct AdjTable { //邻接表 Vertex * NodeTable; //顶点表

int NumVertices; //当前顶点个数 int NumEdges; //当前边数

}

//下列算法是根据一个图的邻接矩阵建立该图的邻接表,请在 处填入合适 //的内容,使其成为一个完整的算法。

AdjTable * convertM ( ) {

//将图的邻接矩阵(用this指针指示)转换为邻接表,函数返回邻接表的地址。 AdjTable * A; Edge *e;

A->NodeTable = new Vertex[NumVertices]; A->NumEdges = NumEdges;

A->NumVertices = NumVertices;

for ( int i = 0; i < NumVertices; i++ ) { A->NodeTable[i].data = NodeTable[i]; A->NodeTable[i].adj = (1) ;

for ( int j = 0; j < NumVertices; j++ )

19

if ( arr[i][j] != INFINITY && arr[i][j] != 0 ) { e = new Edge;

e->dest = j;

e->cost= (2) ;

e->link = A->NodeTable[i].adj;

(3) ; } }

return A; }

7. 已知带权图的邻接矩阵表示和邻接表类表示的形式描述分别如下:

(1) 邻接矩阵的定义

#define INFINITY INT_MAX //INT_MAX为最大整数,表示∞const int MaxVertices = 20;

template struct AdjMatrix { Type * NodeTable; //顶点表定义 float arr[Maxvertices][MaxVertices]; //邻接矩阵定义

int NumVertices; //当前顶点个数 int NumEdges; //当前边数

}; (2) 邻接表定义

struct Edge { //邻接表中边结点的定义 int dest; //邻接的结点 float cost;

//边的权值

Edge * link;

}; template struct Vertex { //邻接表中顶点的定义

Type data;

Edge *adj; };

template struct AdjTable { //邻接表 Vertex * NodeTable; //顶点表

int NumVertices; //当前顶点个数 int NumEdges; //当前边数

}

//下列算法是根据一个图的邻接表存储结构建立该图的邻接矩阵存储结构, //请在 处填入合适的内容,使其成为一个完整的算法

AdjMatrix * convertAL( ) {

//将图的邻接表(用this指针指示)转换为邻接矩阵,函数返回邻接矩阵的地址。 AdjMatrix * A; int i, j; Edge *p; A->NodeTable = new Vertex[NumVertices];

A->arr = new float [Maxvertices][MaxVertices];

A->NumEdges = NumEdges;

20

A->NumVertices = NumVertices;

for ( i = 0; i < NumVertices; i++ ) {

for ( j = 0; j < NumVertices; j++ ) A->arr[i][j] = INFINITY;

A->NodeTable[i] = _______ __(1)___ ______; }

for ( i = 0; i < NumVertices; i++ ) {

p = NodeTable[i].adj;

while ( p != NULL ) {

A->arr[i][p->dest] = ___ __(2)__________; ________________(3)________________; } }

}

8. 已知图的邻接表和逆邻接表的形式描述如下:

struct Edge { //结点定义 int dest;

//邻接结点

float cost; //边的权值

Edge * link;

};

template struct Vertex { //顶点定义

Type data;

Edge *adj; };

template struct Graph { //邻接表与逆邻接表定义Vertex * NodeTable; //邻接表顶点表

Vertex * OppositNodeTable; //逆邻接表顶点表 int NumVertices; //当前顶点个数 int NumEdges; //当前边数

}

//下列算法是根据一个图的邻接表存储结构建立该图的逆邻接表存储结构,请 //在 处填入合适的内容,使其成为一个完整的算法。

void convertM ( ) {

int i; Edge *p, *q;

OppositNodeTable = new Vertex[NumVertices]; for ( i = 0; i < NumVertices; i++ ) {

OppositNodeTable[i].data = NodeTable[i].data; OppositNodeTable[i].adj = NULL; }

for ( i = 0; i < NumVertices; i++ ) {

p = NodeTable[i].adj; while ( p != NULL ) {

q = new Edge;

q->dest = i;

21

q->cost = p->cost;

_________ ____(1)____ _________; OppositNodeTable[p->dest].adj = q; ______________(2)_____________;

} }

}

参考答案:

1. (1) 执行操作后的返回值是5。 (2) 算法的功能是计算有向图中一个顶点的度。 算法的时间复杂度是O(n),n为图的顶点个数。

2. 执行操作G.unknown (3) 后,图的邻接矩阵为:

0 1 1 0 1 0 0 0 0 0

A = 0 0 0 0 1

0 0 0 0 0

0 0 0 0 0 算法的功能是从图中删除所有与某个顶点相关的边。

3. 填空结果

(1) 0 //2分

(2) Degree[p->dest]++ //2分

(3) Degree[i]++ //2分 ( 注:

4. 填空结果

(1) p != NULL && p->dest != i (2) deg++;

5. 填空结果

(1) p != NULL && p->dest != i //3(2) NodeTable[j].adj = p->link;

6. 填空结果

(1) NULL (2) arr[i][j] (3) A->NodeTable[i].adj = e

7. 填空结果

(1) NodeTable[i].data (2) p->cost (3) p = p->link

8. 填空结果

//2分 //2分 //2分

//3分 //3分 互换也正确 ) //3分

//3分

分 //3分 //2分 //2分

//2分

//2分 //2分 //2分

22

(2), (3)(1) q->link = OppositNodeTable[p->dest].adj (2) p = p->link

//3分 //3分

六、算法设计题

1. 试编写函数用邻接表存储结构实现

template int AdjTable ::GetFirstNeighbor ( int v );

//给出顶点位置为v 的第一个邻接顶点的位置,如果找不到,则函数返回-1

2. 用邻接表存储结构实现带权有向图的构造函数

template AdjTable :: AdjTable ( int sz = DefaultSize ) :

MaxVertices(sz) { ……输入顶点个数、数据及各条边的信息,建立邻接表…… }

3. 试编写函数用邻接表存储结构实现

template int AdjTable ::GetNextNeighbor ( int v, int w );

//给出顶点v的邻接顶点w的下一个邻接顶点的位置,若没有下一个邻接顶点,则函数返回-1 参考答案

1. 算法实现如下

template int AdjTable ::GetFirstNeighbor ( int v ) { //给出顶点位置为v 的第一个邻接顶点的位置,如果找不到,则函数返回-1

if ( v != -1 ) {

}

2. 算法实现如下

template AdjTable ::AdjTable ( int sz = DefaultSize ) :

MaxVertices ( sz ) {

int i, k, j; Type tail, head; float weight; Edge *p; NodeTalbe = new Vertex[MaxVertices]; cin >> NumVertices;

for ( i = 0; i < NumVertices; i++ ) {

cin >> NodeTable[i].data; NodeTable[i].adj = NULL; }

cin >> NumEdges;

//4分

Edge *p = NodeTable (v).adj; if ( p != NULL ) return p->dest; }

return –1;

//4分 //4分

for ( i = 0; i < NumEdges; i++ ) { //4分

cin >> tail >> head >> weight;

k = GetVertexPos(tail); j = GetVertexPos(head); p = new Edge;

p->dest = j; p->cost = weight;

23

p->link = NodeTable[k].adj; NodeTable[k].adj = p; } }

3. 算法实现如下

template int AdjTable ::GetNextNeighbor ( int v, int w ) { //给出顶点v的邻接顶点w的下一个邻接顶点的位置,若没有下一个邻接顶点,则 //函数返回-1

if ( v != -1 ) {

Edge * p = NodeTable[v].adj;

while ( p != NULL )

if (p->dest == w && p->link != NULL ) return p->link->dest; else p = p->link;

}

return –1; }

24

本文来源:https://www.bwwdw.com/article/vmqp.html

Top