第七章 图
一、单选题
( C )1. 在一个图中,所有顶点的度数之和等于图的边数的 倍。
A.1/2 B. 1 C. 2 D. 4
2. 在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的( B )倍。
A.1/2 B. 1 C. 2 D. 4
( B )3. 有8个结点的无向图最多有 条边。
A.14 B. 28 C. 56 D. 112
( A )一个n个顶点的连通无向图,其边的个数至少为( )。
A.n-1 B.n C.n+1 D.nlogn;
( C )5. 有8个结点的有向完全图有 条边。
A.14 B. 28 C. 56 D. 112
( B )6. 用邻接表表示图进行广度优先遍历时,通常是采用 来实现算法的。
A.栈 B. 队列 C. 树 D. 图
( A )7. 用邻接表表示图进行深度优先遍历时,通常是采用 来实现算法的。
A.栈 B. 队列 C. 树 D. 图
8. 下面关于求关键路径的说法不正确的是( C )。
A.求关键路径是以拓扑排序为基础的
B.一个事件的最早开始时间同以该事件为尾的弧的活动最早开始时间相同
C.一个事件的最迟开始时间为以该事件为尾的弧的活动最迟开始时间与该活动的持续时间的差
D.关键活动一定位于关键路径上
9. 已知图的邻接矩阵如下,根据算法思想,则从顶点0出发,按深度优先遍历的结点序列是( D )
A. 0 2 4 3 1 5 6 B. 0 1 3 5 6 4 2 C. 0 4 2 3 1 6 5 D. 0 1 3 4 2 5 6
10、设数据结构A=(D,R),其中D={1,2,3,4},R={r},r={<1,2>,<2,3>,<3,4>,<4,1>,<4,2>},则数据结构A是( C )。
(A) 线性结构 (B) 树型结构 (C) 图型结构 (D) 集合
( C )11. 已知图的邻接矩阵同上题9,根据算法,则从顶点0出发,按广度优先遍历的结点序列是
A. 0 2 4 3 1 6 5 B. 0 1 3 5 6 4 2 C. 0 1 2 3 4 6 5 D. 0 1 2 3 4 5 6
12. 已知图的邻接表如下所示,根据算法,则从顶点0出发按深度优先遍历的结点序列是( D )
( A )13. 已知图的邻接表如下所示,根据算法,则从顶点0出发按广度优先遍历的结点序列是
( A )14. 深度优先遍历类似于二叉树的
A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历
( D )15. 广度优先遍历类似于二叉树的
A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历
( D )16、下面结构中最适于表示稀疏无向图的是。
A.邻接矩阵 B.逆邻接表 C.十字链表 D.邻接表
( B )17、下列哪一种图的邻接矩阵是对称矩阵?
A.有向图 B.无向图 C.AOV网 D.AOE网
18、在含n个顶点和e条边的无向图的邻接矩阵中,零元素的个数为( D )
A.e B.2e C.n2-e D.n2-2e
19、下列关于无向连通图特性的叙述中,正确的是 (A)
I.所有顶点的度之和为偶数 II.边数大于顶点个数减1 III.至少有一个顶点的度为1
A.只有I B. 只有II C.I和II D.I和III
20、假设一个有n个顶点和e条弧的有向图用邻接表表示,则删除与某个顶点vi相关的所有弧的时间复杂度是( C )
A.O(n) B.O(e) C.O(n+e) D.O(n*e)
21、无向图G=(V,E),其中:V={a,b,c,d,e,f}, E={(a,b),(a,e),(a,c),(b,e),(c,f),(f,d),(e,d)},对该图进行深度优先遍历,得到的顶点序列正确的是( )。
A.a,b,e,c,d,f B.a,c,f,e,b,d C.a,e,b,c,f,d D.a,e,d,f,c,b
22、在有向图G的拓扑序列中,若顶点Vi在顶点Vj之前,则下列情形不可能出现的是( D )。
A.G中有弧<Vi,Vj> B.G中有一条从Vi到Vj的路径
C.G中没有弧<Vi,Vj> D.G中有一条从Vj到Vi的路径
23、下面哪一方法可以判断出一个有向图是否有环(回路)( B)
A.深度优先遍历 B. 拓扑排序 C. 求最短路径 D. 求关键路径
24、下列关于AOE网的叙述中,不正确的是( B )。
A.关键活动不按期完成就会影响整个工程的完成时间
B.任何一个关键活动提前完成,那么整个工程将会提前完成
C.所有的关键活动提前完成,那么整个工程将会提前完成
D.某些关键活动提前完成,那么整个工程将会提前完成
25、设无向图G中有n个顶点e条边,则其对应的邻接表中的表头结点和表结点的个数分别为( D )。
(A) n,e (B) e,n (C) 2n,e (D) n,2e
二、填空题
1. 图有 邻接矩阵 、邻接表 、十字链表、邻接多重表等存储结构,其中邻接矩阵 、邻接表既用于存储有向图,也用于存储无向图。
遍历图 深度优先遍历、 广度优先遍历 等方法。
2. 有向图G用邻接表矩阵存储,其第i行的所有元素之和等于顶点i的 出度 。
3. 拓扑排序算法是通过重复选择具有 0 个前驱顶点的过程来完成的。
4. n个顶点e条边的图,若采用邻接矩阵存储,则空间复杂度为O(n2),若采用邻接表存储,则空间复杂度为O(n+e)。
5. n个顶点e条边的图采用邻接矩阵存储,广度优先遍历算法的时间复杂度为 O(n2) ;若采用邻接表存储,该算法的时间复杂度为O(n+e)。
6. 设有一稀疏图G,则G采用 邻接表 存储较省空间,设有一稠密图G,则G采用邻接矩阵存储较省空间。
7. 用Dijkstra算法求某一顶点到其余各顶点间的最短路径是按路径长度递增的次序来得到最短路径的。
8. n个顶点的连通无向图,其边的条数至少为__ n-1____。若用n表示图中顶点数目,则有___ n(n-1)/2____条边的无向图成为完全图。
9. 具有8个顶点的有向完全图有 56条弧。具有10个顶点的无向图,边的总数最多为_ 45_。
10. 在无向图G的邻接矩阵A中,若A[i][j]等于1,则A[j][i]等于 1 。
11. G是一个非连通无向图,共有28条边,则该图至少有_9_个顶点。
12. 为了实现图的广度优先搜索,除了一个标志数组标志已访问的图的结点外,还需_队列存放被访问的结点以实现遍历。
13. 一无向图G(V,E),其中V(G)={1,2,3,4,5,6,7},E(G)={(1,2),(1,3),(2,4),(2,5),(3,6),(3,7),(6,7)(5,1)},对该图从顶点3开始进行遍历,去掉遍历中未走过的边,得一生成树G’(V,E’),V(G’)=V(G),E(G’)={(1,3),(3,6),(7,3),(1,2),(1,5),(2,4)},则采用的遍历方法是___广度优先遍历___
14. 在图G的邻接表表示中,每个顶点邻接表中所含的结点数,对于无向图来说等于该顶点的_度_;对于有向图来说等于该顶点的_出度_。
15. 已知一无向图G=(V,E),其中V={a,b,c,d,e } E={(a,b),(a,d),(a,c),(d,c),(b,e)}现用某一种图遍历方法从顶点a开始遍历图,得到的序列为abecd,则采用的是__深度优先遍历方法。
三、判断题
1、(( )在拓朴序列中,如果结点Vi排在结点Vj的前面,则一定存在从Vi到Vj的路径。
2、(√ )用邻接矩阵法存储一个图时,在不考虑压缩存储的情况下,所占用的存储空间大小只与图中结点个数有关,而与图的边数无关。
3、(× )拓扑排序是按AOE网中每个结点事件的最早发生时间对结点进行排序。
4(× )采用邻接表存储的图的深度优先遍历算法类似二叉树的按层次遍历算法。
5、(√ )若一个有向图的邻接矩阵中对角线以下元素均为零,则该图的拓扑有序序列必定存在。
6.在n个结点的无向图中,若边数大于n-1,则该图必是连通图。( × )
7. 有e条边的无向图,在邻接表中有e个结点。( × )
8. 有向图中顶点V的度等于其邻接矩阵中第V行中的1的个数。( × )
9.强连通图的各顶点间均可达。( √ )
10.连通分量指的是有向图中的极大连通子图。( × )
11.任何有向图的结点都可以排成拓扑排序,而且拓扑序列不唯一。( × )
12.用邻接矩阵法存储一个图所需的存储单元数目与图的边数有关。( × )
13.有n个顶点的无向图, 采用邻接矩阵表示, 图中的边数等于邻接矩阵中非零元素之和的一半。( √ )
14. 当改变网上某一关键路径上任一关键活动后,必将产生不同的关键路径( × )
15.不同的求最小生成树的方法最后得到的生成树是相同的.( × )
16、有向图的邻接表和逆邻接表中表结点的个数一定相等。(√ )
四、简答题
1.请对下图的无向带权图:
写出它的邻接矩阵,并按普里姆算法求其最小生成树;
写出它的邻接表,并按克鲁斯卡尔算法求其最小生成树。
解:设起点为a。可以直接由原始图画出最小生成树,而且最小生成树只有一种(类)!
邻接矩阵为:
2.已知二维数组表示的图的邻接矩阵如下图所示。试分别画出自顶点1出发进行遍历所得的深度优先生成树和广度优先生成树。
解:
3、图2表示一个地区的通讯网,边表示城市间的通讯线路,边上的权值表示架设线路花费的代价,请找出能连通每个城市、且总代价最省的n-1条线路。
答:
图2
4、B = (K, R), K = {k1, k2, …, k9}
R={<k1, k3>, <k1, k8>, <k2, k3>,<k2, k4>, <k2, k5>, <k3, k9>,<k5, k6>, <k8, k9>, <k9, k7>, <k4, k7>, <k4, k6>}
分别对关系r中的开始结点,举出一个拓扑序列的例子。
解:开始结点:(入度为0)K1,K2,终端结点(出度为0)K6,K7。
拓扑序列K1,K2,K3,K4,K5,K6,K8,K9,K7
K2,K1,K3,K4,K5,K6,K8,K9,K7
规则:开始结点为K1或K2,之后,若遇多个入度为0的顶点,按顶点编号顺序选择。
5. 已知有向图如下所示,对该图进行拓扑排序。
答:拓扑序列为:A、B、C、D、E、F、G、H、I(不唯一)
6.已知图的邻接矩阵为:
V1
V2
V3
V4
V5
V6
V7
V8
V9
V10
V1
0
1
1
1
0
0
0
0
0
0
V2
0
0
0
1
1
0
0
0
0
0
V3
0
0
0
1
0
1
0
0
0
0
V4
0
0
0
0
0
1
1
0
1
0
V5
0
0
0
0
0
0
1
0
0
0
V6
0
0
0
0
0
0
0
1
1
0
V7
0
0
0
0
0
0
0
0
1
0
V8
0
0
0
0
0
0
0
0
0
1
V9
0
0
0
0
0
0
0
0
0
1
V10
0
0
0
0
0
0
0
0
0
0
当用邻接表作为图的存储结构,且邻接表都按序号从大到小排序时,试写出:
(1).以顶点V1为出发点的唯一的深度优先遍历;
(2).以顶点V1为出发点的唯一的广度优先遍历;
(3).该图唯一的拓扑有序序列。
7.已知一数据集合的逻辑结构为:B = (K, R), 其中,K = {k1, k2, …, k8},R={<k1, k4>, <k1, k8>, <k2, k3>,<k2, k4>, <k3, k5>, <k3, k7>, <k5 k7>, <k5, k6>,<k6, k7>,<K8,K6>},请回答下面两个问题:
(1)画出这个逻辑结构的图示。
(2)写出关系R的一个拓扑序列。
(2)拓扑序列K1,K2,K3,K4,K8,K5,K6,K7
六、算法设计题
1.编写算法,由依次输入的顶点数目、弧的数目、各顶点的信息和各条弧的信息建立有向图的邻接表。
解:Status Build_AdjList(ALGraph &G) //输入有向图的顶点数,边数,顶点信息和边的信息建立邻接表
{ InitALGraph(G);
scanf("%d",&v);
if(v<0) return ERROR; //顶点数不能为负
G.vexnum=v;
scanf("%d",&a);
if(a<0) return ERROR; //边数不能为负
G.arcnum=a;
for(m=0;m<v;m++)
G.vertices[m].data=getchar(); //输入各顶点的符号
for(m=1;m<=a;m++)
{
t=getchar();h=getchar(); //t为弧尾,h为弧头
if((i=LocateVex(G,t))<0) return ERROR;
if((j=LocateVex(G,h))<0) return ERROR; //顶点未找到
p=(ArcNode*)malloc(sizeof(ArcNode));
if(!G.vertices.[i].firstarc) G.vertices[i].firstarc=p;
else
{
for(q=G.vertices[i].firstarc;q->nextarc;q=q->nextarc);
q->nextarc=p;
}
p->adjvex=j;p->nextarc=NULL;
}//while
return OK;
}//Build_AdjList
2.试在邻接矩阵存储结构上实现图的基本操作:DeleteArc(G,v,w) ,即删除一条边的操作。(如果要删除所有从第i个顶点出发的边呢? 提示: 将邻接矩阵的第i行全部置0 )
解://本题中的图G均为有向无权图。
Status Delete_Arc(MGraph &G,char v,char w)//在邻接矩阵表示的图G上删除边(v,w)
{
if((i=LocateVex(G,v))<0) return ERROR;
if((j=LocateVex(G,w))<0) return ERROR;
if(G.arcs[i][j].adj)
{
G.arcs[i][j].adj=0;
G.arcnum--;
}
return OK;
}//Delete_Arc
3.试基于图的深度优先搜索策略写一算法,判别以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径(i≠j)。注意:算法中涉及的图的基本操作必须在此存储结构上实现。
int visited[MAXSIZE]; //指示顶点是否在当前路径上
int exist_path_DFS(ALGraph G,int i,int j)//深度优先判断有向图G中顶点i到顶点j
是否有路径,是则返回1,否则返回0
{
if(i==j) return 1; //i就是j
else
{
visited[i]=1;
for(p=G.vertices[i].firstarc;p;p=p->nextarc)
{
k=p->adjvex;
if(!visited[k]&&exist_path(k,j)) return 1;//i下游的顶点到j有路径
}//for
}//else
}//exist_path_DFS