第七章图习题数据结构Word文件下载.docx
《第七章图习题数据结构Word文件下载.docx》由会员分享,可在线阅读,更多相关《第七章图习题数据结构Word文件下载.docx(19页珍藏版)》请在冰点文库上搜索。
![第七章图习题数据结构Word文件下载.docx](https://file1.bingdoc.com/fileroot1/2023-4/30/38d3489a-6bb6-4af3-90a8-1a9f469752f2/38d3489a-6bb6-4af3-90a8-1a9f469752f21.gif)
A.G中有弧<
Vi,Vj>
B.G中有一条从Vi到Vj的路径
C.G中没有弧<
Vi,Vj>
D.G中有一条从Vj到Vi的路径
14.关键路径是事件结点网络中()。
A.从源点到汇点的最长路径B.从源点到汇点的最短路径
C.最长回路D.最短回路
15.下列关于AOE网的叙述中,不正确的是()。
A.关键活动不按期完成就会影响整个工程的完成时间
B.任何一个关键活动提前完成,那么整个工程将会提前完成
C.所有的关键活动提前完成,那么整个工程将会提前完成
D.某些关键活动提前完成,那么整个工程将会提前完成
二、填空题
1.具有10个顶点的无向图,边的总数最多为______。
2.设无向图G有n个顶点和e条边,每个顶点Vi的度为di(1<
=i<
=n),则e=______
3.在有n个顶点的有向图中,若要使任意两点间可以互相到达,则至少需要______条弧。
4.下图中的强连通分量的个数为______个。
5.N个顶点的连通图用邻接矩阵表示时,该矩阵至少有_______个非零元素。
6.在有向图的邻接矩阵表示中,计算第I个顶点入度的方法是______。
7.对于一个具有n个顶点e条边的无向图的邻接表的表示,则表头向量大小为______,邻接表的边结点个数为______。
8.已知一无向图G=(V,E),其中V={a,b,c,d,e}E={(a,b),(a,d),(a,c),(d,c),(b,e)}现用某一种图遍历方法从顶点a开始遍历图,得到的序列为abecd,则采用的是______遍历方法。
9.构造连通网最小生成树的两个典型算法是______。
10.有向图G可拓扑排序的判别条件是______。
11.Dijkstra最短路径算法从源点到其余各顶点的最短路径的路径长度按______次序依次产生,该算法弧上的权出现______情况时,不能正确产生最短路径。
12.有向图G=(V,E),其中V(G)={0,1,2,3,4,5},用<
a,b,d>
三元组表示弧<
及弧上的权d.E(G)为{<
0,5,100>
0,2,10>
<
1,2,5>
0,4,30>
4,5,60>
3,5,10>
2,3,50>
4,3,20>
},则从源点0到顶点3的最短路径长度是______,经过的中间顶点是______。
13.AOV网中,结点表示______,边表示______。
AOE网中,结点表示______,边表示______。
14.在AOE网中,从源点到汇点路径上各活动时间总和最长的路径称为______。
15.在AOV网中,存在环意味着______,这是______的;
对程序的数据流图来说,它表明存在______。
16.如下为拓扑排序的C程序,
(1).列出对右图执行该程序后的输出结果。
______
(2).在程序空白处填上适当语句。
voidtopsort(hdnodesgraph[],intn)
{inti,j,k,top;
node_pointerptr;
top=-1;
for(i=0;
i<
n;
i++)
if(!
graph[i].count){graph[i].count=top;
top=i;
}
if
(1)____{fprintf(stderr,"
\ngraphhasacycle\n"
);
exit
(1);
else{j=top;
(2)_____;
printf("
v%d,"
j);
for(ptr=graph[j].link;
ptr;
ptr=ptr->
link)
{k=ptr->
vertex;
graph[k].count--;
if((3)_____){graph[k].count=top;
top=k;
}}}
}
三、应用题
1.已知如图所示的有向图,请给出该图的:
(1)
每个顶点的入度、出度;
(2)
邻接矩阵;
(3)
邻接表;
(4)
逆邻接表;
(5)
强连通分量。
2.已知图的邻接矩阵为:
V1
V2
V3
V4
V5
V6
V7
V8
V9
V10
1
当用邻接表作为图的存储结构,且邻接表都按序号从大到小排序时,试写出:
(1).以顶点V1为出发点的唯一的深度优先遍历;
(2).以顶点V1为出发点的唯一的广度优先遍历;
(3).该图唯一的拓扑有序序列。
3.已知一个无向图如下图所示,要求分别用Prim和Kruskal算法生成最小树(假设以①为起点,试画出构造过程)。
4.已知世界六大城市为:
北京(Pe)、纽约(N)、巴黎(Pa)、伦敦(L)、东京(T)、墨西哥(M),下表给定了这六大城市之间的交通里程:
世界六大城市交通里程表(单位:
百公里)
pe
n
pa
L
T
M
Pe
109
82
81
21
124
N
58
55
108
32
PA
3
97
92
95
89
113
(1).画出这六大城市的交通网络图;
(2).画出该图的邻接表表示法;
(3).画出该图按权值递增的顺序来构造的最小(代价)生成树.
5.下表给出了某工程各工序之间的优先关系和各工序所需时间
(1).画出相应的AOE网
(2).列出各事件的最早发生时间,最迟发生时间
(3).找出关键路径并指明完成该工程所需最短时间.
工序代号
A
B
C
D
E
F
G
H
I
J
K
L
M
N
所需时间
15
10
50
8
15
40
300
120
60
30
20
先驱工作
--
A,B
C,D
G,I
F,I
H,J,K
四、算法设计题
1.已知有向图有n个顶点,请写算法,根据用户输入的偶对建立该有向图的邻接表。
即接受用户输入的<
vi,vj>
(以其中之一为0标志结束),对于每条这样的边,申请一个结点,并插入到的单链表中,如此反复,直到将图中所有边处理完毕。
提示:
先产生邻接表的n个头结点(其结点数值域从1到n)。
2.设已给出图的邻接矩阵,要求将邻接矩阵转换为邻接表。
3.已知无向图采用邻接表存储方式,试写出删除边(i,j)的算法。
4.假设以邻接矩阵作为图的存储结构,编写算法判别在给定的有向图中是否存在一个简单有向回路,若存在,则以顶点序列的方式输出该回路(找到一条即可)。
(注:
图中不存在顶点到自己的弧)
5.给定n个村庄之间的交通图,若村庄i和j之间有道路,则将顶点i和j用边连接,边上的Wij表示这条道路的长度,现在要从这n个村庄中选择一个村庄建一所医院,问这所医院应建在哪个村庄,才能使离医院最远的村庄到医院的路程最短?
试设计一个解答上述问题的算法,并应用该算法解答如图所示的实例。
6.对于一个使用邻接表存储的有向图G,可以利用深度优先遍历方法,对该图中结点进行拓扑排序。
其基本思想是:
在遍历过程中,每访问一个顶点,就将其邻接到的顶点的入度减一,并对其未访问的、入度为0的邻接到的顶点进行递归。
(1).给出完成上述功能的图的邻接表定义(结构)。
(2).定义在算法中使用的全局辅助数组。
(3).写出在遍历图的同时进行拓扑排序的算法。
第七章图
1.B
2.B
3.B
4.A
5.B
6.B
7.BC
8.B
9.C
10.B
11.B
12.A
13.D
14.A
15.B
1.45
2.略
3.n
4.3
5.2(N-1)
6.第I列非零元素个数
7.n2e
8.深度优先
9.普里姆(prim)算法和克鲁斯卡尔(Kruskal)算法
10.不存在环
11.递增负值
12.50,经过中间顶点④
13.
(1)活动
(2)活动间的优先关系(3)事件(4)活动边上的权代表活动持续时间
14.关键路径
15.
(1)某项活动以自己为先决条件
(2)荒谬(3)死循环
16.1)V1V4V3V6V2V5(尽管图以邻接表为存储结构,但因没规定邻接点的排列,所以结果是不唯一的。
本答案是按邻接点升序排列给出的。
)
(2)①top==-1②top=graph[j].count③graph[k].count==0
1.【解答】
(1)顶点入度出度
130
222
312
413
521
623
邻接矩阵
(3)邻接表
(4)逆邻接表
(5)强连通分量
2.略
3.为节省篇幅,这里仅用Kruskal算法,构造最小生成树过程如下:
(下图也可选(2,4)代替(3,4),(5,6)代替(1,5))
4.
(1)
(2)略
(3)最小生成树6个顶点5条边:
V(G)={Pe,N,Pa,L,T,M}
E(G)={(L,Pa,3),(Pe,T,21),(M,N,32),(L,N,55),(L,Pe,81)}
5.
(1)AOE网图略
(2)各事件发生的最早和最晚时间如下表
事件
2
4
5
6
7
8
9
10
11
12
最早发生时间
15
65
50
80
200
380
395
425
445
420
最晚发生时间
57
335
(3)关键路径为顶点序列:
1->
2->
4->
6->
8->
9->
10->
11;
事件序列:
A->
C->
E->
G->
H->
L->
M,完成工程所需的最短时间为445。
1.
voidCreatAdjList(AdjListg)
//建立有向图的邻接表存储结构
{intn;
scanf("
%d"
&
n);
for(i=1;
i<
=n;
j++)
{scanf(&
g[i].vertex);
g[i].firstarc=null;
}//输入顶点信息
scanf(&
v1,.&
v2);
while(v1&
&
v2)//题目要求两顶点之一为0表示结束
{i=GraphLocateVertex(g2,v1);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->
adjvex=j;
next=g[i].firstarc;
g[i].firstarc=p;
v1,&
}}
2.voidAdjMatrixToAdjList(AdjMatrixgm,AdjListgl)
//将图的邻接矩阵表示法转换为邻接表表示法。
{for(i=1;
i++)//邻接表表头向量初始化。
gl[i].vertex);
gl[i].firstarc=null;
}
for(i=1;
i++)
for(j=1;
j<
if(gm[i][j]==1)
{p=(ArcNode*)malloc(sizeof(ArcNode));
//申请结点空间。
p->
//顶点I的邻接点是j
next=gl[i].firstarc;
gl[i].firstarc=p;
//链入顶点i的邻接点链表中
}//end
[算法讨论]算法中邻接表中顶点在向量表中的下标与其在邻接矩阵中的行号相同。
3.voidDeletEdge(AdjListg,inti,j)
//在用邻接表方式存储的无向图g中,删除边(i,j)
{p=g[i].firstarc;
pre=null;
//删顶点i的边结点(i,j),pre是前驱指针
while(p)
if(p->
adjvex==j)
{if(pre==null)g[i].firstarc=p->
next;
elsepre->
next=p->
free(p);
}//释放结点空间。
else{pre=p;
p=p->
}//沿链表继续查找
p=g[j].firstarc;
//删顶点j的边结点(j,i)
adjvex==i)
{if(pre==null)g[j].firstarc=p->
}//DeletEdge
[算法讨论]算法中假定给的i,j均存在,否则应检查其合法性。
若未给顶点编号,而给出顶点信息,则先用顶点定位函数求出其在邻接表顶点向量中的下标i和j。
4.[题目分析]有向图判断回路要比无向图复杂。
利用深度优先遍历,将顶点分成三类:
未访问;
已访问但其邻接点未访问完;
已访问且其邻接点已访问完。
下面用0,1,2表示这三种状态。
前面已提到,若dfs(v)结束前出现顶点u到v的回边,则图中必有包含顶点v和u的回路。
对应程序中v的状态为1,而u是正访问的顶点,若我们找出u的下一邻接点的状态为1,就可以输出回路了。
voidPrint(intv,intstart)//输出从顶点start开始的回路。
{for(i=1;
if(g[v][i]!
=0&
visited[i]==1)//若存在边(v,i),且顶点i的状态为1。
{printf(“%d”,v);
if(i==start)printf(“\n”);
elsePrint(i,start);
break;
}//if
}//Print
voiddfs(intv)
{visited[v]=1;
for(j=1;
j++)
if(g[v][j]!
=0)//存在边(v,j)
if(visited[j]!
=1){if(!
visited[j])dfs(j);
}//if
else{cycle=1;
Print(j,j);
visited[v]=2;
}//dfs
voidfind_cycle()//判断是否有回路,有则输出邻接矩阵。
visited数组为全局变量。
{for(i=1;
i++)visited[i]=0;
i++)if(!
visited[i])dfs(i);
}//find_cycle
5.[题目分析]该题可用求每对顶点间最短路径的FLOYD算法求解。
求出每一顶点(村庄)到其它顶点(村庄)的最短路径。
在每个顶点到其它顶点的最短路径中,选出最长的一条。
因为有n个顶点,所以有n条,在这n条最长路径中找出最短一条,它的出发点(村庄)就是医院应建立的村庄。
voidHospital(AdjMatrixw,intn)
//在以邻接带权矩阵表示的n个村庄中,求医院建在何处,使离医院最远的村庄到医院的路径最短。
{for(k=1;
k<
k++)//求任意两顶点间的最短路径
if(w[i][k]+w[k][j]<
w[i][j])w[i][j]=w[i][k]+w[k][j];
m=MAXINT;
//设定m为机器内最大整数。
i++)//求最长路径中最短的一条。
{s=0;
j++)//求从某村庄i(1<
=n)到其它村庄的最长路径。
if(w[i][j]>
s)s=w[i][j];
if(s<
=m){m=s;
k=i;
}//在最长路径中,取最短的一条。
m记最长路径,k记出发顶点的下标。
Printf(“医院应建在%d村庄,到医院距离为%d\n”,i,m);
}//for
}//算法结束
对以上实例模拟的过程略。
在A(6)矩阵中(见下图),各行中最大数依次是9,9,6,7,9,9。
这几个最大数中最小者为6,故医院应建在第三个村庄中,离医院最远的村庄到医院的距离是6。
6.[题目分析]对有向图进行深度优先遍历可以判定图中是否有回路。
若从有向图某个顶点v出发遍历,在dfs(v)结束之前,出现从顶点u到顶点v的回边,图中必存在环。
这里设定visited访问数组和finished数组为全局变量,若finished[i]=1,表示顶点i的邻接点已搜索完毕。
由于dfs产生的是逆拓扑排序,故设一类型是指向邻接表的边结点的全局指针变量final,在dfs函数退出时,把顶点v插入到final所指的链表中,链表中的结点就是一个正常的拓扑序列。
邻接表的定义与本书相同,这里只写出拓扑排序算法。
intvisited[]=0;
finished[]=0;
flag=1;
//flag测试拓扑排序是否成功
ArcNode*final=null;
//final是指向顶点链表的指针,初始化为0
voiddfs(AdjListg,vertypev)
//以顶点v开始深度优先遍历有向图g,顶点信息就是顶点编号.
{ArcNode*t;
//指向边结点的临时变量
printf("
v);
visited[v]=1;
p=g[v].firstarc;
while(p!
=null)
{j=p->
adjvex;
if(visited[j]==1&
finished[j]==0)flag=0//dfs结束前出现回边
elseif(visited[j]==0){dfs(g,j);
finished[j]=1;
}//if
}//while
t=(ArcNode*)malloc(sizeof(ArcNode));
//申请边结点
t->
adjvex=v;
next=final;
final=t;
//将该顶点插入链表
}//dfs结束
intdfs-Topsort(Adjlistg)
//对以邻接表为存储结构的有向图进行拓扑排序,拓扑排序成功返回1,否则返回0
{i=1;
while(flag&
i<
=n)
if(visited[i]==0){dfs(g,i);
finished[i]=1;
return(flag);
}//dfs-Topsort