数据结构(C语言)第二版 第六章课后答案
1~5 C B B B C
6~10 B A B A A
11~15 D C C (D,D) B
1.选择题
(1)在一个图中,所有顶点的度数之和等于图的边数的(C)倍。
A. 1/2 B. 1 C. 2 D. 4
任意一条边都对应2个度,所以度数总和是边数总和的两倍。
(2)在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的(B)倍。
A. 1/2 B. 1 C. 2 D. 4
有向图所有顶点的入度之和等于所有顶点的出度之和
(3)具有n 个顶点的有向图最多有(B)条边。
A. n B . n(n-1) C. n(n+1) D . n2
有向图的边有方向之分, 即为从n个顶点中选取 2 个顶点有序排列, 结果为n(n-1)
(4) n 个顶点的连通图用邻接距阵表示时,该距阵至少有(B) 个非零元素。
A. n B . 2(n-1) C. n/2D . n2
连通图一定是无向图,有向的叫做强连通图,连通n个顶点,至少只需要n-1条边就可以,由于无向图的每条边同时关联两个顶点,因此邻接矩阵中每条边被存储了两次,因此至少有2(n-1)个非零元素
(5) G 是一个非连通无向图,共有28 条边,则该图至少有(C)个顶点。
A. 7 B . 8 C. 9 D . 10
8 个顶点的无向图最多有8*7/2=28 条边,再添加一个点即构成非连通无向图,故至少有9 个顶点。
(6)若从无向图的任意一个顶点出发进行一次深度优先搜索可以访问图中所有的顶点,则该图一定是(B)图。
A.非连通 B .连通 C.强连通 D .有向
即从该无向图任意一个顶点出发有到各个顶点的路径, 所以该无向图是连通图。
(7)下面(A)算法适合构造一个稠密图G 的最小生成树。
A. Prim 算法B . Kruskal 算法C. Floyd 算法D. Dijkstra 算法
Prim 算法适合构造一个稠密图G 的最小生成树, Kruskal 算法适合构造一个稀疏图G 的最小生成树。
(8)用邻接表表示图进行广度优先遍历时,通常借助(B)来实现算法。
A.栈B. 队列C. 树D .图
广度优先遍历通常借助队列来实现算法,深度优先遍历通常借助栈来实现算法。
(9)用邻接表表示图进行深度优先遍历时,通常借助(A)来实现算法。
A.栈B. 队列C. 树D .图
广度优先遍历通常借助队列来实现算法,深度优先遍历通常借助栈来实现算法。
(10)图的深度优先遍历类似于二叉树的(A) 。
A.先序遍历B.中序遍历C.后序遍历D.层次遍历
因为图的深度优先遍历算法先访问所在结点,再访问它的邻接点。与二叉树的先序遍历先访问子树的根结点,再访问它的孩子结点(邻接点)类似。
( 11)图的广度优先遍历类似于二叉树的(D) 。
A.先序遍历B .中序遍历C.后序遍历D.层次遍历
图的广度优先遍历算法类似于二叉树的按层次遍历。
(12)图的 BFS 生成树的树高比 DFS 生成树的树高(C) 。
A.小B.相等C.小或相等D.大或相等
对于一些特殊的图,比如只有一个顶点的图,其BFS 生成树的树高和DFS 生
成树的树高相等。一般的图,根据图的BFS 生成树和DFS 树的算法思想, BFS 生成树的树高比DFS 生成树的树高小。
(13)已知图的邻接矩阵如图6.30 所示, 则从顶点v0 出发按深度优先遍历的结果是(C)。
按深度优先遍历:先访问所在结点,再访问它的邻接点,访问过的跳过找下一个未访问的结点,直到访问完所有的结点。即0-1-3-4-2-5-6
(14)已知图的邻接表如图6.31 所示,则从顶点v0 出发按广度优先遍历的结果是(D) ,按深度优先遍历的结果是(D) 。
(15)下面(B)方法可以判断出一个有向图是否有环。
A. 求最小生成树B. 拓扑排序C. 求最短路径D .求关键路径
判断有没有环的方法
深度优先排序
广度优先排序
拓扑排序
2.应用题
(1)已知图6.32 所示的有向图,请给出:
①每个顶点的入度和出度;
②邻接矩阵;
③邻接表;
④逆邻接表。
答案:
(2)已知如图6.33 所示的无向网,请给出:
①邻接矩阵;
②邻接表;
③最小生成树
(3)已知图的邻接矩阵如图6.34 所示。试分别画出自顶点1 出发进行遍历所得的深度优先生成树和广度优先生成树。
(4)有向网如图6.35 所示,试用迪杰斯特拉算法求出从顶点a 到其他各顶点间的最短路径,完成表6.9 。
(5)试对图6.36 所示的AOE- 网:
① 求这个工程最早可能在什么时间结束;
②求每个活动的最早开始时间和最迟开始时间;
③确定哪些活动是关键活动
按拓扑有序的顺序计算各个顶点的最早可能开始时间Ve 和最迟允许开始时间Vl。然后再计算各个活动的最早可能开始时间e 和最迟允许开始时间l ,根据l-e = 0? 来确定关键活动,从而确定关键路径。
3.算法设计题
(1)分别以邻接矩阵和邻接表作为存储结构,实现以下图的基本操作:
①增加一个新顶点v, InsertVex(G, v) ;
②删除顶点v 及其相关的边, DeleteVex(G , v);
③增加一条边<v , w>, InsertArc(G , v, w);
④删除一条边<v , w>, DeleteArc(G , v, w) 。
[ 算法描述]
//以邻接矩阵作为存储结构
//增加一个新顶点v
Status Insert_Vex(MGraph &G, char v){
if((G.vexnum+1)>MAX_VERTEX_NUM) return INFEASIBLE;
G.vexs[++G.vexnum]=v;
return OK;
}
//删除顶点v 及其相关的边,
Status Delete_Vex(MGraph &G,char v){
n=G.vexnum;
if((m=LocateVex(G,v))<0) return ERROR;
G.vexs[m]<->G.vexs[n]; // 将待删除顶点交换到最后一个顶点
for(i=0;i<n;i++){
G.arcs[m]=G.arcs[n];
G.arcs[m]=G.arcs[n]; // 将边的关系随之交换
}
G.arcs[m][m].adj=0;
G.vexnum--;
return OK;
}
//增加一条边<v , w>
Status Insert_Arc(MGraph &G,char v,char w){
if((i=LocateVex(G,v))<0) return ERROR;
if((j=LocateVex(G,w))<0) return ERROR;
if(i==j) return ERROR;
if(!G.arcs[j].adj){
G.arcs[j].adj=1;
G.arcnum++;
}
return OK;
}
//删除一条边<v , w>
Status Delete_Arc(MGraph &G,char v,char w){
if((i=LocateVex(G,v))<0) return ERROR;
if((j=LocateVex(G,w))<0) return ERROR;
if(G.arcs[j].adj){
G.arcs[j].adj=0;
G.arcnum--;
}
return OK;
}
//以邻接表作为存储结构
Status Insert_Arc(ALGraph &G,char v,char w){
if((i=LocateVex(G,v))<0) return ERROR;
if((j=LocateVex(G,w))<0) return ERROR;
p=new ArcNode;
p->adjvex=j;p->nextarc=NULL;
if(!G.vertices.firstarc) G.vertices.firstarc=p;
else{
for(q=G.vertices.firstarc;q->q->nextarc;q=q->nextarc)
if(q->adjvex==j) return ERROR; // 边已经存在
q->nextarc=p;
}
G.arcnum++;
return OK;
}
(2)一个连通图采用邻接表作为存储结构,设计一个算法,实现从顶点v 出发的深度优先遍历的非递归过程。
[ 算法描述]
Void DFSn(Graph G,int v){ // 从第v 个顶点出发非递归实现深度优先遍历图G
Stack s;
SetEmpty(s);
Push(s,v);
While(!StackEmpty(s)){
Pop(s,k);
If(!visited[k]){
visited[k]=TRUE;
VisitFunc(k);
for(w=FirstAdjVex(G,k);w;w=NextAdjVex(G,k,w)){
if(!visited[w]&&w!=GetTop(s)) Push(s,w);
}
}
}
}
(3)设计一个算法,求图G 中距离顶点v 的最短路径长度最大的一个顶点,设v 可达其余各个顶点。
[ 算法描述]
int ShortestPath _ MAX(AMGraph G,int v0){
n=G.vexnum;
for(v = 0; v<n;++v){
S[v] = false;
D[v] = G.arcs[v0][v];
if(D[v]< MaxInt) Path [v]=v0;
else Path [v]=-1;
}
S[v0]=true;
D[v0]=0;
for(i=1;i<n; ++i){
min= MaxInt;
for(w=0;w<n; ++w)
if(!S[w]&&D[w]<min){v=w; min=D[w];}
S[v]=true;
for(w=0;w<n; ++w)
if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){
D[w]=D[v]+G.arcs[v][w];
Path [w]=v;
}
}
Max=D[0];
m=0;
for(i=1;i<n;i++)
if(Max<D[i]) m=i;
return m;
}
(4)试基于图的深度优先搜索策略写一算法, 判别以邻接表方式存储的有向图中是否存在由顶点v i 到顶点v j 的路径( i≠ j )。
[ 算法描述]
int visited[MAXSIZE];
int level = 1;
int exist_path_DFS(ALGraph G,int i,int j){
if(i==j) return 1;
else{
visited[i]=1;
for(p=G.vertices[i].firstarc;p;p=p->nextarc , level--){
level++;
k=p->adjvex;
if(!visited[k]&&exist_path(k,j)) return 1;
}
}
if (level==1) return 0;
}
(5)采用邻接表存储结构,编写一个算法,判别无向图中任意给定的两个顶点之间是否存在一条长度为为k 的简单路径。
[ 算法描述]
int visited[MAXSIZE];
int exist_path_len(ALGraph G,int i,int j,int k){
if(i==j&&k==0) return 1;
else if(k>0){
visited[i]=1;
for(p=G.vertices[i].firstarc;p;p=p->nextarc){
l=p->adjvex;
if(!visited[l])
if(exist_path_len(G,l,j,k-1)) return 1;
}
visited[i]=0;
}
return 0;
}