第8章 图习题与解析.docx
- 文档编号:8681192
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:33
- 大小:25.71KB
第8章 图习题与解析.docx
《第8章 图习题与解析.docx》由会员分享,可在线阅读,更多相关《第8章 图习题与解析.docx(33页珍藏版)》请在冰豆网上搜索。
第8章图习题与解析
第七章图
7.1知识要点
7.2习题解析
7.2.1选择题
7.2.2判断题
第七章图
7.14
StatusBuild_AdjList(ALGraph&G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接表
{
InitALGraph(G);
scanf("%d",&v);
if(v<0)returnERROR;//顶点数不能为负
G.vexnum=v;
scanf("%d",&a);
if(a<0)returnERROR;//边数不能为负
G.arcnum=a;
for(m=0;m G.vertices[m].data=getchar();//输入各顶点的符号 for(m=1;m<=a;m++) { t=getchar();h=getchar();//t为弧尾,h为弧头 if((i=LocateVex(G,t))<0)returnERROR; if((j=LocateVex(G,h))<0)returnERROR;//顶点未找到 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 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; returnOK; }//Insert_Vex StatusInsert_Arc(MGraph&G,charv,charw)//在邻接矩阵表示的图G上插入边(v,w) { if((i=LocateVex(G,v))<0)returnERROR; if((j=LocateVex(G,w))<0)returnERROR; if(i==j)returnERROR; if(! G.arcs[i][j].adj) { G.arcs[i][j].adj=1; G.arcnum++; } returnOK; }//Insert_Arc StatusDelete_Vex(MGraph&G,charv)//在邻接矩阵表示的图G上删除顶点v { n=G.vexnum; if((m=LocateVex(G,v))<0)returnERROR; G.vexs[m]<->G.vexs[n];//将待删除顶点交换到最后一个顶点 for(i=0;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--; returnOK; }//Delete_Vex 分析: 如果不把待删除顶点交换到最后一个顶点的话,算法将会比较复杂,而伴随着大量元素的移动,时间复杂度也会大大增加. StatusDelete_Arc(MGraph&G,charv,charw)//在邻接矩阵表示的图G上删除边(v,w) { if((i=LocateVex(G,v))<0)returnERROR; if((j=LocateVex(G,w))<0)returnERROR; if(G.arcs[i][j].adj) { G.arcs[i][j].adj=0; G.arcnum--; } returnOK; }//Delete_Arc 7.16 //为节省篇幅,本题只给出Insert_Arc算法.其余算法请自行写出. StatusInsert_Arc(ALGraph&G,charv,charw)//在邻接表表示的图G上插入边(v,w) { if((i=LocateVex(G,v))<0)returnERROR; if((j=LocateVex(G,w))<0)returnERROR; p=(ArcNode*)malloc(sizeof(ArcNode)); p->adjvex=j;p->nextarc=NULL; if(! G.vertices[i].firstarc)G.vertices[i].firstarc=p; else { for(q=G.vertices[i].firstarc;q->q->nextarc;q=q->nextarc) if(q->adjvex==j)returnERROR;//边已经存在 q->nextarc=p; } G.arcnum++; returnOK; }//Insert_Arc 7.17 //为节省篇幅,本题只给出较为复杂的Delete_Vex算法.其余算法请自行写出. StatusDelete_Vex(OLGraph&G,charv)//在十字链表表示的图G上删除顶点v { if((m=LocateVex(G,v))<0)returnERROR; n=G.vexnum; for(i=0;i { if(G.xlist[i].firstin->tailvex==m)//如果待删除的边是头链上的第一个结点 { q=G.xlist[i].firstin; G.xlist[i].firstin=q->hlink; free(q);G.arcnum--; } else//否则 { for(p=G.xlist[i].firstin;p&&p->hlink->tailvex! =m;p=p->hlink); if(p) { q=p->hlink; p->hlink=q->hlink; free(q);G.arcnum--; } }//else }//for for(i=0;i { if(G.xlist[i].firstout->headvex==m)//如果待删除的边是尾链上的第一个结点 { q=G.xlist[i].firstout; G.xlist[i].firstout=q->tlink; free(q);G.arcnum--; } else//否则 { for(p=G.xlist[i].firstout;p&&p->tlink->headvex! =m;p=p->tlink); if(p) { q=p->tlink; p->tlink=q->tlink; free(q);G.arcnum--; } }//else }//for for(i=m;i { G.xlist[i]=G.xlist[i+1];//修改表头向量 for(p=G.xlist[i].firstin;p;p=p->hlink) p->headvex--; for(p=G.xlist[i].firstout;p;p=p->tlink) p->tailvex--;//修改各链中的顶点序号 } G.vexnum--; returnOK; }//Delete_Vex 7.18 //为节省篇幅,本题只给出Delete_Arc算法.其余算法请自行写出. StatusDelete_Arc(AMLGraph&G,charv,charw)////在邻接多重表表示的图G上删除边(v,w) { if((i=LocateVex(G,v))<0)returnERROR; if((j=LocateVex(G,w))<0)returnERROR; if(G.adjmulist[i].firstedge->jvex==j) G.adjmulist[i].firstedge=G.adjmulist[i].firstedge->ilink; else { for(p=G.adjmulist[i].firstedge;p&&p->ilink->jvex! =j;p=p->ilink); if(! p)returnERROR;//未找到 p->ilink=p->ilink->ilink; }//在i链表中删除该边 if(G.adjmulist[j].firstedge->ivex==i) G.adjmulist[j].firstedge=G.adjmulist[j].firstedge->jlink; else { for(p=G.adjmulist[j].firstedge;p&&p->jlink->ivex! =i;p=p->jlink); if(! p)returnERROR;//未找到 q=p->jlink; p->jlink=q->jlink; free(q); }//在i链表中删除该边 G.arcnum--; returnOK; }//Delete_Arc 7.19 StatusBuild_AdjMulist(AMLGraph&G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接多重表 { InitAMLGraph(G); scanf("%d",&v); if(v<0)returnERROR;//顶点数不能为负 G.vexnum=v; scanf(%d",&a); if(a<0)returnERROR;//边数不能为负 G.arcnum=a; for(m=0;m G.adjmulist[m].data=getchar();//输入各顶点的符号 for(m=1;m<=a;m++) { t=getchar();h=getchar();//t为弧尾,h为弧头 if((i=LocateVex(G,t))<0)returnERROR; if((j=LocateVex(G,h))<0)returnERROR;//顶点未找到 p=(EBox*)malloc(sizeof(EBox)); p->ivex=i;p->jvex=j; p->ilink=NULL;p->jlink=NULL;//边结点赋初值 if(! G.adjmulist[i].firstedge)G.adjmulist[i].firstedge=p; else { q=G.adjmulist[i].firstedge; while(q) { r=q; if(q->ivex==i)q=q->ilink; elseq=q->jlink; } if(r->ivex==i)r->ilink=p;//注意i值既可能出现在边结点的ivex域中, elser->jlink=p;//又可能出现在边结点的jvex域中 }//else//插入i链表尾部 if(! G.adjmulist[j].firstedge)G.adjmulist[j].firstedge=p; else { q=G.adjmulist[i].firstedge; while(q) { r=q; if(q->jvex==j)q=q->jlink; elseq=q->ilnk; } if(r->jvex==j)r->jlink=p; elser->ilink=p; }//else//插入j链表尾部 }//for returnOK; }//Build_AdjList 7.20 intPass_MGraph(MGraphG)//判断一个邻接矩阵存储的有向图是不是可传递的,是则返回1,否则返回0 { for(x=0;x for(y=0;y if(G.arcs[x][y]) { for(z=0;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(x=0;x for(p=G.vertices[x].firstarc;p;p=p->nextarc) { y=p->adjvex; for(q=G.vertices[y].firstarc;q;q=q->nextarc) { z=q->adjvex; if(z! =x&&! is_adj(G,x,z))return0; }//for }//for }//Pass_ALGraph intis_adj(ALGraphG,intm,intn)//判断有向图G中是否存在边(m,n),是则返回1,否则返回0 { for(p=G.vertices[m].firstarc;p;p=p->nextarc) 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 else { visited[i]=1; for(p=G.vertices[i].firstarc;p;p=p->nextarc) { k=p->adjvex; if(! visited[k]&&exist_path(k,j))return1;//i下游的顶点到j有路径 }//for }//else }//exist_path_DFS 7.23 intexist_path_BFS(ALGraphG,inti,intj)//广度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0 { intvisited[MAXSIZE]; InitQueue(Q); EnQueue(Q,i); while(! QueueEmpty(Q)) { DeQueue(Q,u); visited[u]=1; for(p=G.vertices[i].firstarc;p;p=p->nextarc) { k=p->adjvex; if(k==j)return1; if(! visited[k])EnQueue(Q,k); }//for }//while return0; }//exist_path_BFS 7.24 voidSTraverse_Nonrecursive(GraphG)//非递归遍历强连通图G { intvisited[MAXSIZE]; InitStack(S); Push(S,GetVex(S,1));//将第一个顶点入栈 visit (1); visited=1; while(! StackEmpty(S)) { while(Gettop(S,i)&&i) { j=FirstAdjVex(G,i); if(j&&! visited[j]) { visit(j); visited[j]=1; Push(S,j);//向左走到尽头 } }//while if(! StackEmpty(S)) { Pop(S,j); Gettop(S,i); k=NextAdjVex(G,i,j);//向右走一步 if(k&&! visited[k]) { visit(k); visited[k]=1; Push(S,k); } }//if }//while }//Straverse_Nonrecursive 分析: 本算法的基本思想与二叉树的先序遍历非递归算法相同,请参考6.37.由于是强连通图,所以从第一个结点出发一定能够访问到所有结点. 7.25 见书后解答. 7.26 StatusTopoNo(ALGraphG)//按照题目要求顺序重排有向图中的顶点 { intnew[MAXSIZE],indegree[MAXSIZE];//储存结点的新序号 n=G.vexnum; FindInDegree(G,indegree); InitStack(S); for(i=1;i if(! indegree[i])Push(S,i);//零入度结点入栈 count=0; while(! StackEmpty(S)) { Pop(S,i); new[i]=n--;//记录结点的拓扑逆序序号 count++; for(p=G.vertices[i].firstarc;p;p=p->nextarc) { k=p->adjvex; if(! (--indegree[k]))Push(S,k); }//for }//while if(count for(i=1;i<=n;i++)printf("OldNo: %dNewNo: %d\n",i,new[i]) returnOK; }//TopoNo 分析: 只要按拓扑逆序对顶点编号,就可以使邻接矩阵成为下三角矩阵. 7.27 intvisited[MAXSIZE]; intexist_path_len(ALGraphG,inti,intj,intk)//判断邻接表方式存储的有向图G的顶点i到j是否存在长度为k的简单路径 { if(i==j&&k==0)return1;//找到了一条路径,且长度符合要求 elseif(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))return1;//剩余路径长度减一 }//for visited[i]=0;//本题允许曾经被访问过的结点出现在另一条路径中 }//else return0;//没找到 }//exist_path_len 7.28 intpath[MAXSIZE],visited[MAXSIZE];//暂存遍历过程中的路径 intFind_All_Path(ALGraphG,intu,intv,intk)//求有向图G中顶点u到v之间的所有简单路径,k表示当前路径长度 { path[k]=u;//加入当前路径中 visited[u]=1; if(u==v)//找到了一条简单路径 { printf("Foundonepath! \n"); for(i=0;path[i];i++)printf("%d",path[i]);//打印输出 } else for(p=G.vertices[u].firstarc;p;p=p->nextarc) { l=p->adjvex; if(! 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之间长度
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第8章 图习题与解析 习题 解析