第8章 图习题与解析Word文件下载.docx
《第8章 图习题与解析Word文件下载.docx》由会员分享,可在线阅读,更多相关《第8章 图习题与解析Word文件下载.docx(33页珍藏版)》请在冰豆网上搜索。
![第8章 图习题与解析Word文件下载.docx](https://file1.bdocx.com/fileroot1/2023-1/31/e2780871-2c99-46fc-a7bb-27e655475004/e2780871-2c99-46fc-a7bb-27e6554750041.gif)
if((j=LocateVex(G,h))<
//顶点未找到
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);
nextarc=p;
}
p->
adjvex=j;
nextarc=NULL;
}//while
returnOK;
}//Build_AdjList
7.15
//本题中的图G均为有向无权图,其余情况容易由此写出
StatusInsert_Vex(MGraph&
G,charv)//在邻接矩阵表示的图G上插入顶点v
if(G.vexnum+1)>
MAX_VERTEX_NUMreturnINFEASIBLE;
G.vexs[++G.vexnum]=v;
}//Insert_Vex
StatusInsert_Arc(MGraph&
G,charv,charw)//在邻接矩阵表示的图G上插入边(v,w)
if((i=LocateVex(G,v))<
if((j=LocateVex(G,w))<
if(i==j)returnERROR;
G.arcs[i][j].adj)
G.arcs[i][j].adj=1;
G.arcnum++;
}//Insert_Arc
StatusDelete_Vex(MGraph&
G,charv)//在邻接矩阵表示的图G上删除顶点v
n=G.vexnum;
if((m=LocateVex(G,v))<
G.vexs[m]<
->
G.vexs[n];
//将待删除顶点交换到最后一个顶点
for(i=0;
i<
n;
i++)
G.arcs[i][m]=G.arcs[i][n];
G.arcs[m][i]=G.arcs[n][i];
//将边的关系随之交换
G.arcs[m][m].adj=0;
G.vexnum--;
}//Delete_Vex
分析:
如果不把待删除顶点交换到最后一个顶点的话,算法将会比较复杂,而伴随着大量元素的移动,时间复杂度也会大大增加.
StatusDelete_Arc(MGraph&
G,charv,charw)//在邻接矩阵表示的图G上删除边(v,w)
if(G.arcs[i][j].adj)
G.arcs[i][j].adj=0;
G.arcnum--;
}//Delete_Arc
7.16
//为节省篇幅,本题只给出Insert_Arc算法.其余算法请自行写出.
StatusInsert_Arc(ALGraph&
G,charv,charw)//在邻接表表示的图G上插入边(v,w)
G.vertices[i].firstarc)G.vertices[i].firstarc=p;
nextarc)
if(q->
adjvex==j)returnERROR;
//边已经存在
7.17
//为节省篇幅,本题只给出较为复杂的Delete_Vex算法.其余算法请自行写出.
StatusDelete_Vex(OLGraph&
G,charv)//在十字链表表示的图G上删除顶点v
i++)//删除所有以v为头的边
if(G.xlist[i].firstin->
tailvex==m)//如果待删除的边是头链上的第一个结点
q=G.xlist[i].firstin;
G.xlist[i].firstin=q->
hlink;
free(q);
else//否则
for(p=G.xlist[i].firstin;
p&
&
hlink->
tailvex!
=m;
p=p->
hlink);
if(p)
q=p->
hlink=q->
}//else
}//for
i++)//删除所有以v为尾的边
if(G.xlist[i].firstout->
headvex==m)//如果待删除的边是尾链上的第一个结点
q=G.xlist[i].firstout;
G.xlist[i].firstout=q->
tlink;
for(p=G.xlist[i].firstout;
tlink->
headvex!
tlink);
tlink=q->
for(i=m;
i++)//顺次用结点m之后的顶点取代前一个顶点
G.xlist[i]=G.xlist[i+1];
//修改表头向量
p;
hlink)
headvex--;
tlink)
tailvex--;
//修改各链中的顶点序号
}//Delete_Vex
7.18
//为节省篇幅,本题只给出Delete_Arc算法.其余算法请自行写出.
StatusDelete_Arc(AMLGraph&
G,charv,charw)////在邻接多重表表示的图G上删除边(v,w)
if(G.adjmulist[i].firstedge->
jvex==j)
G.adjmulist[i].firstedge=G.adjmulist[i].firstedge->
ilink;
for(p=G.adjmulist[i].firstedge;
ilink->
jvex!
=j;
ilink);
if(!
p)returnERROR;
//未找到
ilink=p->
}//在i链表中删除该边
if(G.adjmulist[j].firstedge->
ivex==i)
G.adjmulist[j].firstedge=G.adjmulist[j].firstedge->
jlink;
for(p=G.adjmulist[j].firstedge;
jlink->
ivex!
=i;
jlink);
jlink=q->
7.19
StatusBuild_AdjMulist(AMLGraph&
G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接多重表
InitAMLGraph(G);
scanf(%d"
G.adjmulist[m].data=getchar();
p=(EBox*)malloc(sizeof(EBox));
ivex=i;
jvex=j;
ilink=NULL;
jlink=NULL;
//边结点赋初值
G.adjmulist[i].firstedge)G.adjmulist[i].firstedge=p;
q=G.adjmulist[i].firstedge;
while(q)
r=q;
ivex==i)q=q->
elseq=q->
if(r->
ivex==i)r->
ilink=p;
//注意i值既可能出现在边结点的ivex域中,
elser->
jlink=p;
//又可能出现在边结点的jvex域中
}//else//插入i链表尾部
G.adjmulist[j].firstedge)G.adjmulist[j].firstedge=p;
jvex==j)q=q->
ilnk;
jvex==j)r->
}//else//插入j链表尾部
7.20
intPass_MGraph(MGraphG)//判断一个邻接矩阵存储的有向图是不是可传递的,是则返回1,否则返回0
for(x=0;
x<
G.vexnum;
x++)
for(y=0;
y<
y++)
if(G.arcs[x][y])
for(z=0;
z<
z++)
if(z!
=x&
G.arcs[y][z]&
!
G.arcs[x][z])return0;
//图不可传递的条件
}//if
return1;
}//Pass_MGraph
本算法的时间复杂度大概是O(n^2*d).
7.21
intPass_ALGraph(ALGraphG)//判断一个邻接表存储的有向图是不是可传递的,是则返回1,否则返回0
for(p=G.vertices[x].firstarc;
y=p->
adjvex;
for(q=G.vertices[y].firstarc;
q;
z=q->
is_adj(G,x,z))return0;
}//Pass_ALGraph
intis_adj(ALGraphG,intm,intn)//判断有向图G中是否存在边(m,n),是则返回1,否则返回0
for(p=G.vertices[m].firstarc;
if(p->
adjvex==n)return1;
return0;
}//is_adj
7.22
intvisited[MAXSIZE];
//指示顶点是否在当前路径上
intexist_path_DFS(ALGraphG,inti,intj)//深度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0
if(i==j)return1;
//i就是j
visited[i]=1;
for(p=G.vertices[i].firstarc;
k=p->
visited[k]&
exist_path(k,j))return1;
//i下游的顶点到j有路径
}//exist_path_DFS
7.23
intexist_path_BFS(ALGraphG,inti,intj)//广度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0
InitQueue(Q);
EnQueue(Q,i);
while(!
QueueEmpty(Q))
DeQueue(Q,u);
visited[u]=1;
if(k==j)return1;
visited[k])EnQueue(Q,k);
}//exist_path_BFS
7.24
voidSTraverse_Nonrecursive(GraphG)//非递归遍历强连通图G
InitStack(S);
Push(S,GetVex(S,1));
//将第一个顶点入栈
visit
(1);
visited=1;
StackEmpty(S))
while(Gettop(S,i)&
i)
j=FirstAdjVex(G,i);
if(j&
visited[j])
visit(j);
visited[j]=1;
Push(S,j);
//向左走到尽头
Pop(S,j);
Gettop(S,i);
k=NextAdjVex(G,i,j);
//向右走一步
if(k&
visited[k])
visit(k);
visited[k]=1;
Push(S,k);
}//Straverse_Nonrecursive
本算法的基本思想与二叉树的先序遍历非递归算法相同,请参考6.37.由于是强连通图,所以从第一个结点出发一定能够访问到所有结点.
7.25
见书后解答.
7.26
StatusTopoNo(ALGraphG)//按照题目要求顺序重排有向图中的顶点
intnew[MAXSIZE],indegree[MAXSIZE];
//储存结点的新序号
FindInDegree(G,indegree);
for(i=1;
indegree[i])Push(S,i);
//零入度结点入栈
count=0;
Pop(S,i);
new[i]=n--;
//记录结点的拓扑逆序序号
count++;
(--indegree[k]))Push(S,k);
if(count<
G.vexnum)returnERROR;
//图中存在环
=n;
i++)printf("
OldNo:
%dNewNo:
%d\n"
i,new[i])
}//TopoNo
只要按拓扑逆序对顶点编号,就可以使邻接矩阵成为下三角矩阵.
7.27
intexist_path_len(ALGraphG,inti,intj,intk)//判断邻接表方式存储的有向图G的顶点i到j是否存在长度为k的简单路径
if(i==j&
k==0)return1;
//找到了一条路径,且长度符合要求
elseif(k>
0)
l=p->
visited[l])
if(exist_path_len(G,l,j,k-1))return1;
//剩余路径长度减一
visited[i]=0;
//本题允许曾经被访问过的结点出现在另一条路径中
//没找到
}//exist_path_len
7.28
intpath[MAXSIZE],visited[MAXSIZE];
//暂存遍历过程中的路径
intFind_All_Path(ALGraphG,intu,intv,intk)//求有向图G中顶点u到v之间的所有简单路径,k表示当前路径长度
path[k]=u;
//加入当前路径中
if(u==v)//找到了一条简单路径
printf("
Foundonepath!
\n"
);
path[i];
path[i]);
//打印输出
for(p=G.vertices[u].firstarc;
visited[l])Find_All_Path(G,l,v,k+1);
//继续寻找
visited[u]=0;
path[k]=0;
//回溯
}//Find_All_Path
main()
...
Find_All_Path(G,u,v,0);
//在主函数中初次调用,k值应为0
}//main
7.29
intGetPathNum_Len(ALGraphG,inti,intj,intlen)//求邻接表方式存储的有向图G的顶点i到j之间长度