数据结构第七章习题课
严蔚敏《数据结构(c语言版)习题集》答案第七章 图
严蔚敏《数据结构(c语言版)习题集》答案第七章图第七章图7.14Status 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;}//whilereturn OK;}//Build_AdjList7.15//本题中的图G均为有向无权图,其余情况容易由此写出Status Insert_Vex(MGraph &G, char v)//在邻接矩阵表示的图G上插入顶点v {if(G.vexnum+1)>MAX_VERTEX_NUM return INFEASIBLE;G.vexs[++G.vexnum]=v;return OK;}//Insert_VexStatus Insert_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(i==j) return ERROR;if(!G.arcs[i][j].adj){G.arcs[i][j].adj=1;G.arcnum++;}return OK;}//Insert_ArcStatus Delete_Vex(MGraph &G,char v)//在邻接矩阵表示的图G上删除顶点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[i][m]=G.arcs[i][n];G.arcs[m][i]=G.arcs[n][i]; //将边的关系随之交换}G.arcs[m][m].adj=0;G.vexnum--;return OK;}//Delete_Vex分析:如果不把待删除顶点交换到最后一个顶点的话,算法将会比较复杂,而伴随着大量元素的移动,时间复杂度也会大大增加.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_Arc7.16//为节省篇幅,本题只给出Insert_Arc算法.其余算法请自行写出.Status Insert_Arc(ALGraph &G,char v,char w)//在邻接表表示的图G上插入边(v,w) {if((i=LocateVex(G,v))<0) return ERROR;if((j=LocateVex(G,w))<0) return ERROR;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) return ERROR; //边已经存在q->nextarc=p;}G.arcnum++;return OK;}//Insert_Arc7.17//为节省篇幅,本题只给出较为复杂的Delete_Vex算法.其余算法请自行写出. Status Delete_Vex(OLGraph &G,char v)//在十字链表表示的图G上删除顶点v { if((m=LocateVex(G,v))<0) return ERROR;n=G.vexnum;for(i=0;i<n;i++) //删除所有以v为头的边{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}//forfor(i=0;i<n;i++) //删除所有以v为尾的边{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}//forfor(i=m;i<n;i++) //顺次用结点m之后的顶点取代前一个顶点{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--;return OK;}//Delete_Vex7.18//为节省篇幅,本题只给出Delete_Arc算法.其余算法请自行写出.Status Delete_Arc(AMLGraph &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.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) return ERROR; //未找到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) return ERROR; //未找到q=p->jlink;p->jlink=q->jlink;free(q);} //在i链表中删除该边G.arcnum--;return OK;}//Delete_Arc7.19Status Build_AdjMulist(AMLGraph &G)//输入有向图的顶点数,边数,顶点信息和边的信息建立邻接多重表{InitAMLGraph(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.adjmulist[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=(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;else q=q->jlink;}if(r->ivex==i) r->ilink=p;//注意i值既可能出现在边结点的ivex域中, else r->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;else q=q->ilnk;}if(r->jvex==j) r->jlink=p;else r->ilink=p;}//else //插入j链表尾部}//forreturn OK;}//Build_AdjList7.20int Pass_MGraph(MGraph G)//判断一个邻接矩阵存储的有向图是不是可传递的,是则返回1,否则返回0{for(x=0;x<G.vexnum;x++)for(y=0;y<G.vexnum;y++)if(G.arcs[x][y]){for(z=0;z<G.vexnum;z++)if(z!=x&&G.arcs[y][z]&&!G.arcs[x][z]) return 0;//图不可传递的条件}//ifreturn 1;}//Pass_MGraph分析:本算法的时间复杂度大概是O(n^2*d).7.21int Pass_ALGraph(ALGraph G)//判断一个邻接表存储的有向图是不是可传递的,是则返回1,否则返回0{for(x=0;x<G.vexnum;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)) return 0;}//for}//for}//Pass_ALGraphint is_adj(ALGraph G,int m,int n)//判断有向图G中是否存在边(m,n),是则返回1,否则返回0{for(p=G.vertices[m].firstarc;p;p=p->nextarc)if(p->adjvex==n) return 1;return 0;}//is_adj7.22int visited[MAXSIZE]; //指示顶点是否在当前路径上int exist_path_DFS(ALGraph G,int i,int j)//深度优先判断有向图G中顶点i到顶点j是否有路径,是则返回1,否则返回0{if(i==j) return 1; //i就是jelse{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_DFS7.23int exist_path_BFS(ALGraph G,int i,int j)//广度优先判断有向图G中顶点i到顶点j是否有是则返回1,否则返回0 路径,{int visited[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) return 1;if(!visited[k]) EnQueue(Q,k);}//for}//whilereturn 0;}//exist_path_BFS7.24void STraverse_Nonrecursive(Graph G)//非递归遍历强连通图G { int visited[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); //向左走到尽头}}//whileif(!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.26Status TopoNo(ALGraph G)//按照题目要求顺序重排有向图中的顶点 { int new[MAXSIZE],indegree[MAXSIZE]; //储存结点的新序号n=G.vexnum;FindInDegree(G,indegree);InitStack(S);for(i=1;i<G.vexnum;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}//whileif(count<G.vexnum) return ERROR; //图中存在环for(i=1;i<=n;i++) printf("Old No:%d New No:%d\n",i,new[i])return OK;}//TopoNo分析:只要按拓扑逆序对顶点编号,就可以使邻接矩阵成为下三角矩阵. 7.27 int visited[MAXSIZE];int exist_path_len(ALGraph G,int i,int j,int k)//判断邻接表方式存储的有向图G的顶点i到j是否存在长度为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; //剩余路径长度减一}//forvisited[i]=0; //本题允许曾经被访问过的结点出现在另一条路径中}//elsereturn 0; //没找到}//exist_path_len7.28int path[MAXSIZE],visited[MAXSIZE]; //暂存遍历过程中的路径 intFind_All_Path(ALGraph G,int u,int v,int k)//求有向图G中顶点u到v之间的所有简单路径,k表示当前路径长度{path[k]=u; //加入当前路径中visited[u]=1;if(u==v) //找到了一条简单路径{printf("Found one path!\n");for(i=0;path[i];i++) printf("%d",path[i]); //打印输出}elsefor(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_Pathmain(){...Find_All_Path(G,u,v,0); //在主函数中初次调用,k值应为0...}//main7.29int GetPathNum_Len(ALGraph G,int i,int j,int len)//求邻接表方式存储的有向图G的顶点i到j之间长度为len的简单路径条数{if(i==j&&len==0) return 1; //找到了一条路径,且长度符合要求else if(len>0){sum=0; //sum表示通过本结点的路径数visited[i]=1;for(p=G.vertices[i].firstarc;p;p=p->nextarc){l=p->adjvex;if(!visited[l])sum+=GetPathNum_Len(G,l,j,len-1)//剩余路径长度减一}//forvisited[i]=0; //本题允许曾经被访问过的结点出现在另一条路径中}//elsereturn sum;}//GetPathNum_Len7.30int visited[MAXSIZE];int path[MAXSIZE]; //暂存当前路径int cycles[MAXSIZE][MAXSIZE]; //储存发现的回路所包含的结点 int thiscycle[MAXSIZE]; //储存当前发现的一个回路 int cycount=0; //已发现的回路个数void GetAllCycle(ALGraph G)//求有向图中所有的简单回路 {for(v=0;v<G.vexnum;v++) visited[v]=0;for(v=0;v<G.vexnum;v++)if(!visited[v]) DFS(G,v,0); //深度优先遍历}//DFSTraversevoid DFS(ALGraph G,int v,int k)//k表示当前结点在路径上的序号 {visited[v]=1;path[k]=v; //记录当前路径for(p=G.vertices[v].firstarc;p;p=p->nextarc){w=p->adjvex;if(!visited[w]) DFS(G,w,k+1);else //发现了一条回路{for(i=0;path[i]!=w;i++); //找到回路的起点for(j=0;path[i+j];i++) thiscycle[j]=path[i+j];//把回路复制下来if(!exist_cycle()) cycles[cycount++]=thiscycle;//如果该回路尚未被记录过,就添加到记录中for(i=0;i<G.vexnum;i++) thiscycle[i]=0; //清空目前回路数组}//else}//forpath[k]=0;visited[k]=0; //注意只有当前路径上的结点visited为真.因此一旦遍历中发现当前结点visited为真,即表示发现了一条回路}//DFSint exist_cycle()//判断thiscycle数组中记录的回路在cycles的记录中是否已经存在 {int temp[MAXSIZE];for(i=0;i<cycount;i++) //判断已有的回路与thiscycle是否相同{ //也就是,所有结点和它们的顺序都相同j=0;c=thiscycle�; //例如,142857和857142是相同的回路for(k=0;cycles[i][k]!=c&&cycles[i][k]!=0;k++);//在cycles的一个行向量中寻找等于thiscycle第一个结点的元素if(cycles[i][k]) //有与之相同的一个元素{for(m=0;cycles[i][k+m];m++)temp[m]=cycles[i][k+m];for(n=0;n<k;n++,m++)temp[m]=cycles[i][n]; //调整cycles中的当前记录的循环相位并放入temp 数组中if(!StrCompare(temp,thiscycle)) //与thiscycle比较return 1; //完全相等for(m=0;m<G.vexnum;m++) temp[m]=0; //清空这个数组}}//forreturn 0; //所有现存回路都不与thiscycle完全相等}//exist_cycle分析:这个算法的思想是,在遍历中暂存当前路径,当遇到一个结点已经在路径之中时就表明存在一条回路;扫描路径向量path可以获得这条回路上的所有结点.把结点序列(例如,142857)存入thiscycle中;由于这种算法中,一条回路会被发现好几次,所以必须先判断该回路是否已经在cycles中被记录过,如果没有才能存入cycles的一个行向量中.把cycles的每一个行向量取出来与之比较.由于一条回路可能有多种存储顺序,比如142857等同于285714和571428,所以还要调整行向量的次序,并存入temp数组,例如,thiscycle为142857第一个结点为1,cycles的当前向量为857142,则找到后者中的1,把1后部分提到1前部分前面,最终在temp中得到142857,与thiscycle比较,发现相同,因此142857和857142是同一条回路,不予存储.这个算法太复杂,很难保证细节的准确性,大家理解思路便可.希望有人给出更加简捷的算法.7.31int visited[MAXSIZE];int finished[MAXSIZE];int count; //count在第一次深度优先遍历中用于指示finished数组的填充位置 void Get_SGraph(OLGraph G)//求十字链表结构储存的有向图G的强连通分量 {count=0;for(v=0;v<G.vexnum;v++) visited[v]=0;for(v=0;v<G.vexnum;v++) //第一次深度优先遍历建立finished数组if(!visited[v]) DFS1(G,v);for(v=0;v<G.vexnum;v++) visited[v]=0; //清空visited数组for(i=G.vexnum-1;i>=0;i--) //第二次逆向的深度优先遍历{v=finished(i);if(!visited[v]){printf("\n"); //不同的强连通分量在不同的行输出DFS2(G,v);}}//for}//Get_SGraphvoid DFS1(OLGraph G,int v)//第一次深度优先遍历的算法{visited[v]=1;for(p=G.xlist[v].firstout;p;p=p->tlink){w=p->headvex;if(!visited[w]) DFS1(G,w);}//forfinished[++count]=v; //在第一次遍历中建立finished数组}//DFS1void DFS2(OLGraph G,int v)//第二次逆向的深度优先遍历的算法 {visited[v]=1;printf("%d",v); //在第二次遍历中输出结点序号for(p=G.xlist[v].firstin;p;p=p->hlink){w=p->tailvex;if(!visited[w]) DFS2(G,w);}//for}//DFS2分析:求有向图的强连通分量的算法的时间复杂度和深度优先遍历相同,也为O(n+e). 7.32void Forest_Prim(ALGraph G,int k,CSTree &T)//从顶点k出发,构造邻接表结构的有向图G的最小生成森林T,用孩子兄弟链表存储{for(j=0;j<G.vexnum;j++) //以下在Prim算法基础上稍作改动if(j!=k){closedge[j]={k,Max_int};for(p=G.vertices[j].firstarc;p;p=p->nextarc)if(p->adjvex==k) closedge[j].lowcost=p->cost;}//ifclosedge[k].lowcost=0;for(i=1;i<G.vexnum;i++){k=minimum(closedge);if(closedge[k].lowcost<Max_int){Addto_Forest(T,closedge[k].adjvex,k); //把这条边加入生成森林中closedge[k].lowcost=0;for(p=G.vertices[k].firstarc;p;p=p->nextarc)if(p->cost<closedge[p->adjvex].lowcost)closedge[p->adjvex]={k,p->cost};}//ifelse Forest_Prim(G,k); //对另外一个连通分量执行算法}//for}//Forest_Primvoid Addto_Forest(CSTree &T,int i,int j)//把边(i,j)添加到孩子兄弟链表表示的树T中 {p=Locate(T,i); //找到结点i对应的指针p,过程略q=(CSTNode*)malloc(sizeof(CSTNode));q->data=j;if(!p) //起始顶点不属于森林中已有的任何一棵树{p=(CSTNode*)malloc(sizeof(CSTNode));p->data=i;for(r=T;r->nextsib;r=r->nextsib);r->nextsib=p;p->firstchild=q;} //作为新树插入到最右侧else if(!p->firstchild) //双亲还没有孩子p->firstchild=q; //作为双亲的第一个孩子else //双亲已经有了孩子{for(r=p->firstchild;r->nextsib;r=r->nextsib);r->nextsib=q; //作为双亲最后一个孩子的兄弟}}//Addto_Forestmain(){...T=(CSTNode*)malloc(sizeof(CSTNode)); //建立树根T->data=1;Forest_Prim(G,1,T);...}//main分析:这个算法是在Prim算法的基础上添加了非连通图支持和孩子兄弟链表构建模块而得到的,其时间复杂度为O(n^2).7.33typedef struct {int vex; //结点序号int ecno; //结点所属的连通分量号} VexInfo; VexInfo vexs[MAXSIZE]; //记录结点所属连通分量号的数组void Init_VexInfo(VexInfo &vexs[ ],int vexnum)//初始化 { for(i=0;i<vexnum;i++)vexs[i]={i,i}; //初始状态:每一个结点都属于不同的连通分量 }//Init_VexInfoint is_ec(VexInfo vexs[ ],int i,int j)//判断顶点i和顶点j是否属于同一个连通分量{if(vexs[i].ecno==vexs[j].ecno) return 1;else return 0;}//is_ecvoid merge_ec(VexInfo &vexs[ ],int ec1,int ec2)//合并连通分量ec1和ec2{for(i=0;vexs[i].vex;i++)if(vexs[i].ecno==ec2) vexs[i].ecno==ec1;}//merge_ecvoid MinSpanTree_Kruscal(Graph G,EdgeSetType &EdgeSet,CSTree &T)//求图的最小生成树的克鲁斯卡尔算法{Init_VexInfo(vexs,G.vexnum);ecnum=G.vexnum; //连通分量个数while(ecnum>1){GetMinEdge(EdgeSet,u,v); //选出最短边if(!is_ec(vexs,u,v)) //u和v属于不同连通分量{Addto_CSTree(T,u,v); //加入到生成树中merge_ec(vexs,vexs[u].ecno,vexs[v].ecno); //合并连通分量ecnum--;}DelMinEdge(EdgeSet,u,v); //从边集中删除}//while}//MinSpanTree_Kruscalvoid Addto_CSTree(CSTree &T,int i,int j)//把边(i,j)添加到孩子兄弟链表表示的树T中 {p=Locate(T,i); //找到结点i对应的指针p,过程略q=(CSTNode*)malloc(sizeof(CSTNode));q->data=j;if(!p->firstchild) //双亲还没有孩子p->firstchild=q; //作为双亲的第一个孩子else //双亲已经有了孩子{for(r=p->firstchild;r->nextsib;r=r->nextsib);r->nextsib=q; //作为双亲最后一个孩子的兄弟}}//Addto_CSTree分析:本算法使用一维结构体变量数组来表示等价类,每个连通分量所包含的所有结点属于一个等价类.在这个结构上实现了初始化,判断元素是否等价(两个结点是否属于同一个连通分量),合并等价类(连通分量)的操作.7.34Status TopoSeq(ALGraph G,int new[ ])//按照题目要求给有向无环图的结点重新编号,并存入数组new中{int indegree[MAXSIZE]; //本算法就是拓扑排序FindIndegree(G,indegree);Initstack(S);for(i=0;i<G.vexnum;i++)if(!indegree[i]) Push(S,i);count=0;while(!stackempty(S)){Pop(S,i);new[i]=++count; //把拓扑顺序存入数组的对应分量中for(p=G.vertices[i].firstarc;p;p=p->nextarc){k=p->adjvex;if(!(--indegree[k])) Push(S,k);}}//whileif(count<G.vexnum) return ERROR;return OK;}//TopoSeq7.35int visited[MAXSIZE];void Get_Root(ALGraph G)//求有向无环图的根,如果有的话{for(v=0;v<G.vexnum;v++){for(w=0;w<G.vexnum;w++) visited[w]=0;//每次都要将访问数组清零DFS(G,v); //从顶点v出发进行深度优先遍历for(flag=1,w=0;w<G.vexnum;w++)if(!visited[w]) flag=0; //如果v是根,则深度优先遍历可以访问到所有结点if(flag) printf("Found a root vertex:%d\n",v);}//for}//Get_Root,这个算法要求图中不能有环,否则会发生误判void DFS(ALGraph G,int v){visited[v]=1;for(p=G.vertices[v].firstarc;p;p=p->nextarc){w=p->adjvex;if(!visited[w]) DFS(G,w);}}//DFS7.36void Fill_MPL(ALGraph &G)//为有向无环图G添加MPL域 {FindIndegree(G,indegree);for(i=0;i<G.vexnum;i++)if(!indegree[i]) Get_MPL(G,i);//从每一个零入度顶点出发构建MPL域 }//Fill_MPLint Get_MPL(ALGraph &G,int i)//从一个顶点出发构建MPL域并返回其MPL 值 {if(!G.vertices[i].firstarc){G.vertices[i].MPL=0;return 0; //零出度顶点}else{max=0;for(p=G.vertices[i].firstarc;p;p=p->nextarc){j=p->adjvex;if(G.vertices[j].MPL==0) k=Get_MPL(G,j);if(k>max) max=k; //求其直接后继顶点MPL的最大者}G.vertices[i]=max+1;//再加一,就是当前顶点的MPLreturn max+1;}//else}//Get_MPL7.37int maxlen,path[MAXSIZE]; //数组path用于存储当前路径 intmlp[MAXSIZE]; //数组mlp用于存储已发现的最长路径 voidGet_Longest_Path(ALGraph G)//求一个有向无环图中最长的路径 { maxlen=0;FindIndegree(G,indegree);for(i=0;i<G.vexnum;i++){for(j=0;j<G.vexnum;j++) visited[j]=0;if(!indegree[i]) DFS(G,i,0);//从每一个零入度结点开始深度优先遍历}printf("Longest Path:");for(i=0;mlp[i];i++) printf("%d",mlp[i]); //输出最长路径 }//Get_Longest_Pathvoid DFS(ALGraph G,int i,int len) {visited[i]=1;path[len]=i;if(len>maxlen&&!G.vertices[i].firstarc) //新的最长路径{for(j=0;j<=len;j++) mlp[j]=path[j]; //保存下来maxlen=len;}else{for(p=G.vertices[i].firstarc;p;p=p->nextarc){j=p->adjvex;if(!visited[j]) DFS(G,j,len+1);}}//elsepath[i]=0;visited[i]=0;}//DFS7.38void NiBoLan_DAG(ALGraph G)//输出有向无环图形式表示的表达式的逆波兰式 {FindIndegree(G,indegree);for(i=0;i<G.vexnum;i++)if(!indegree[i]) r=i; //找到有向无环图的根PrintNiBoLan_DAG(G,i);}//NiBoLan_DAGvoid PrintNiBoLan_DAG(ALGraph G,int i)//打印输出以顶点i为根的表达式的逆波兰式 {c=G.vertices[i].data;if(!G.vertices[i].firstarc) //c是原子printf("%c",c);else //子表达式{p=G.vertices[i].firstarc;PrintNiBoLan_DAG(G,p->adjvex);PrintNiBoLan_DAG(G,p->nexarc->adjvex);printf("%c",c);}}//PrintNiBoLan_DAG7.39void PrintNiBoLan_Bitree(Bitree T)//在二叉链表存储结构上重做上一题 { if(T->lchild) PrintNiBoLan_Bitree(T->lchild);if(T->rchild) PrintNiBoLan_Bitree(T->rchild);printf("%c",T->data);}//PrintNiBoLan_Bitree7.40int Evaluate_DAG(ALGraph G)//给有向无环图表示的表达式求值 { FindIndegree(G,indegree);for(i=0;i<G.vexnum;i++)if(!indegree[i]) r=i; //找到有向无环图的根return Evaluate_imp(G,i); }//NiBoLan_DAGint Evaluate_imp(ALGraph G,int i)//求子表达式的值{if(G.vertices[i].tag=NUM) return G.vertices[i].value;else{p=G.vertices[i].firstarc;v1=Evaluate_imp(G,p->adjvex);v2=Evaluate_imp(G,p->nextarc->adjvex);return calculate(v1,G.vertices[i].optr,v2);}}//Evaluate_imp分析:本题中,邻接表的vertices向量的元素类型修改如下: struct { enum tag{NUM,OPTR};union {int value;char optr;};ArcNode * firstarc;} Elemtype;7.41void Critical_Path(ALGraph G)//利用深度优先遍历求网的关键路径 { FindIndegree(G,indegree);for(i=0;i<G.vexnum;i++)if(!indegree[i]) DFS1(G,i); //第一次深度优先遍历:建立vefor(i=0;i<G.vexnum;i++)if(!indegree[i]) DFS2(G,i); //第二次深度优先遍历:建立vlfor(i=0;i<=G.vexnum;i++)if(vl[i]==ve[i]) printf("%d",i); //打印输出关键路径}//Critical_Pathvoid DFS1(ALGraph G,int i) {if(!indegree[i]) ve[i]=0;for(p=G.vertices[i].firstarc;p;p=p->nextarc) {dut=*p->info;if(ve[i]+dut>ve[p->adjvex])ve[p->adjvex]=ve[i]+dut;DFS1(G,p->adjvex);}}//DFS1void DFS2(ALGraph G,int i) {if(!G.vertices[i].firstarc) vl[i]=ve[i]; else{for(p=G.vertices[i].firstarc;p;p=p->nextarc) {DFS2(G,p->adjvex);dut=*p->info;if(vl[p->adjvex]-dut<vl[i])vl[i]=vl[p->adjvex]-dut;}}//else}//DFS27.42void ALGraph_DIJ(ALGraph G,int v0,Pathmatrix &P,ShortestPathTable &D)//在邻接表存储结构上实现迪杰斯特拉算法{for(v=0;v<G.vexnum;v++)D[v]=INFINITY;for(p=G.vertices[v0].firstarc;p;p=p->nextarc)D[p->adjvex]=*p->info; //给D数组赋初值for(v=0;v<G.vexnum;v++){final[v]=0;for(w=0;w<G.vexnum;w++) P[v][w]=0; //设空路径if(D[v]<INFINITY){P[v][v0]=1;P[v][v]=1;}}//forD[v0]=0;final[v0]=1; //初始化for(i=1;i<G.vexnum;i++){min=INFINITY;for(w=0;w<G.vexnum;w++)if(!final[w])if(D[w]<min) //尚未求出到该顶点的最短路径{v=w;min=D[w];}final[v]=1;for(p=G.vertices[v].firstarc;p;p=p->nextarc){w=p->adjvex;if(!final[w]&&(min+(*p->info)<D[w])) //符合迪杰斯特拉条件{D[w]=min+edgelen(G,v,w);P[w]=P[v];P[w][w]=1; //构造最短路径}}//for}//for}//ALGraph_DIJ分析:本算法对迪杰斯特拉算法中直接取任意边长度的语句作了修改.由于在原算法中,每次循环都是对尾相同的边进行处理,所以可以用遍历邻接表中的一条链来代替.。
数据结构第7章习题答案
第7章 《图》习题参考答案一、单选题(每题1分,共16分)( C )1. 在一个图中,所有顶点的度数之和等于图的边数的倍。
A .1/2 B. 1 C. 2 D. 4 (B )2. 在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的倍。
A .1/2 B. 1 C. 2 D. 4 ( B )3. 有8个结点的无向图最多有条边。
A .14 B. 28 C. 56 D. 112 ( C )4. 有8个结点的无向连通图最少有条边。
A .5 B. 6 C. 7 D. 8 ( C )5. 有8个结点的有向完全图有条边。
A .14 B. 28 C. 56 D. 112 (B )6. 用邻接表表示图进行广度优先遍历时,通常是采用来实现算法的。
A .栈 B. 队列 C. 树 D. 图 ( A )7. 用邻接表表示图进行深度优先遍历时,通常是采用来实现算法的。
A .栈 B. 队列 C. 树 D. 图( C )8. 已知图的邻接矩阵,根据算法思想,则从顶点0出发按深度优先遍历的结点序列是( D )9. 已知图的邻接矩阵同上题8,根据算法,则从顶点0出发,按深度优先遍历的结点序列是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 23465 ( D )10. 已知图的邻接表如下所示,根据算法,则从顶点0出发按深度优先遍历的结点序列是( A )11. 已知图的邻接表如下所示,根据算法,则从顶点0出发按广度优先遍历的结点序列是A .0 2 4 3 1 5 6B. 0 1 3 6 5 4 2C. 0 1 3 4 2 5 6D. 0 3 6 1 5 4 2⎥⎥⎥⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎢⎢⎢⎣⎡0100011101100001011010110011001000110010011011110A .0 1 3 2 B. 0 2 3 1 C. 0 3 2 1 D. 0 1 2 3A.0 3 2 1 B. 0 1 2 3C. 0 1 3 2D. 0 3 1 2(A)12. 深度优先遍历类似于二叉树的A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历(D)13. 广度优先遍历类似于二叉树的A.先序遍历 B. 中序遍历 C. 后序遍历 D. 层次遍历(A)14. 任何一个无向连通图的最小生成树A.只有一棵 B. 一棵或多棵 C. 一定有多棵 D. 可能不存在(注,生成树不唯一,但最小生成树唯一,即边权之和或树权最小的情况唯一)二、填空题(每空1分,共20分)1. 图有邻接矩阵、邻接表等存储结构,遍历图有深度优先遍历、广度优先遍历等方法。
数据结构第7章习题ppt课件
Data Structure
完整版P21P.T0课4.2件021
Page 3
已知以二维数组表示的图的邻接矩阵如图所示。试分别画 出自顶点出发进行遍历所得的深度优先生成树和广度优先 生成树。
Data Structure
完整版0课4.2件021
Page 4
请对下边的无向带权图,
❖ 写出它的邻接矩阵,并按普里姆算法求其最小生成树; ❖ 写出它的邻接表,并按克鲁斯卡尔算法求其最小生成树。
Data Structure
完整版P21P.T0课4.2件021
Page 9
Data Structure
完整版P21P.T0课4.2件021
Page 7
试利用 Dijkstra 算法求下图中从顶点 a 到其它各顶点 间的最短路径,写出执行算法过程中各步的状态。
Data Structure
完整版P21P.T0课4.2件021
Page 8
试利用 Floyd 算法求下图所示有向图中各对顶点之间的 最短路径。
Data Structure
完整版P21P.T0课4.2件021
Page 5
试列出下图中全部可能的拓扑有序序列。
Data Structure
完整版P21P.T0课4.2件021
Page 6
对于下图所示的 AOE 网络,计算各活动弧的 e(ai) 和 l(aj) 函数值,各时间(顶点)的 ve(vi) 和 vl(vj) 函数 值;列出各条关键路径。
数据结构
计算机科学与技术学院
基础知识题
已知有向图,请给出该图的 (1) 每个顶点的入/出度; (2) 邻接矩阵; (3) 邻接表; (4) 逆邻接表; (5) 强连通分量。
数据结构课后习题答案第七章
第七章图(参考答案)7.1(1)邻接矩阵中非零元素的个数的一半为无向图的边数;(2)A[i][j]= =0为顶点,I 和j无边,否则j和j有边相通;(3)任一顶点I的度是第I行非0元素的个数。
7.2(1)任一顶点间均有通路,故是强连通;(2)简单路径V4 V3 V1 V2;(3)0 1 ∞ 1∞ 0 1 ∞1 ∞ 0 ∞∞∞ 1 0邻接矩阵邻接表(2)从顶点4开始的DFS序列:V5,V3,V4,V6,V2,V1(3)从顶点4开始的BFS序列:V4,V5,V3,V6,V1,V27.4(1)①adjlisttp g; vtxptr i,j; //全程变量② void dfs(vtxptr x)//从顶点x开始深度优先遍历图g。
在遍历中若发现顶点j,则说明顶点i和j间有路径。
{ visited[x]=1; //置访问标记if (y= =j){ found=1;exit(0);}//有通路,退出else { p=g[x].firstarc;//找x的第一邻接点while (p!=null){ k=p->adjvex;if (!visited[k])dfs(k);p=p->nextarc;//下一邻接点}}③ void connect_DFS (adjlisttp g)//基于图的深度优先遍历策略,本算法判断一邻接表为存储结构的图g种,是否存在顶点i //到顶点j的路径。
设 1<=i ,j<=n,i<>j.{ visited[1..n]=0;found=0;scanf (&i,&j);dfs (i);if (found) printf (” 顶点”,i,”和顶点”,j,”有路径”);else printf (” 顶点”,i,”和顶点”,j,”无路径”);}// void connect_DFS(2)宽度优先遍历全程变量,调用函数与(1)相同,下面仅写宽度优先遍历部分。
数据结构第七章参考答案
习题71.填空题(1)由10000个结点构成的二叉排序树,在等概率查找的条件下,查找成功时的平均查找长度的最大值可能达到(___________)。
答案:5000.5(2)长度为11的有序序列:1,12,13,24,35,36,47,58,59,69,71进行等概率查找,如果采用顺序查找,则平均查找长度为(___________),如果采用二分查找,则平均查找长度为(___________),如果采用哈希查找,哈希表长为15,哈希函数为H(key)=key%13,采用线性探测解决地址冲突,即d i=(H(key)+i)%15,则平均查找长度为(保留1位小数)(___________)。
答案:6,3,1.6(3)在折半查找中,查找终止的条件为(___________)。
答案:找到匹配元素或者low>high?(4)某索引顺序表共有元素275个,平均分成5块。
若先对索引表采用顺序查找,再对块元素进行顺序查找,则等概率情况下,分块查找成功的平均查找长度是(___________)。
答案:31(5)高度为8的平衡二叉树的结点数至少是(___________)。
答案: 54 计算公式:F(n)=F(n-1)+F(n-2)+1(6)对于这个序列{25,43,62,31,48,56},采用的散列函数为H(k)=k%7,则元素48的同义词是(___________)。
答案:62(7)在各种查找方法中,平均查找长度与结点个数无关的查找方法是(___________)。
答案:散列查找(8)一个按元素值排好的顺序表(长度大于2),分别用顺序查找和折半查找与给定值相等的元素,平均比较次数分别是s和b,在查找成功的情况下,s和b的关系是(___________);在查找不成功的情况下,s和b的关系是(___________)。
答案:(1)(2s-1)b=2s([log2(2s-1)]+1)-2[log2(2s-1)]+1+1(2)分两种情况考虑,见解答。
数据结构第七章的习题答案
数据结构第七章的习题答案数据结构第七章的习题答案数据结构是计算机科学中非常重要的一门学科,它研究如何组织和管理数据以便高效地访问和操作。
第七章是数据结构课程中的一个关键章节,它涵盖了树和二叉树这两个重要的数据结构。
本文将为读者提供第七章习题的详细解答,帮助读者更好地理解和掌握这些概念。
1. 问题:给定一个二叉树,如何判断它是否是二叉搜索树?解答:要判断一个二叉树是否是二叉搜索树,我们可以使用中序遍历的方法。
中序遍历会按照从小到大的顺序访问二叉树中的节点。
所以,如果一个二叉树是二叉搜索树,那么它的中序遍历结果应该是一个有序的序列。
具体实现时,我们可以使用递归或者迭代的方式进行中序遍历,并将遍历的结果保存在一个数组中。
然后,我们检查这个数组是否是有序的即可判断二叉树是否是二叉搜索树。
2. 问题:给定一个二叉树,如何找到它的最大深度?解答:要找到一个二叉树的最大深度,我们可以使用递归的方式。
对于每个节点,它的最大深度等于其左子树和右子树中的最大深度加1。
递归的终止条件是节点为空,此时深度为0。
具体实现时,我们可以定义一个递归函数,该函数接收一个节点作为参数,并返回以该节点为根节点的子树的最大深度。
在递归函数中,我们先判断节点是否为空,如果为空则返回0;否则,我们分别计算左子树和右子树的最大深度,然后取两者中的较大值加1作为当前节点的最大深度。
3. 问题:给定一个二叉树,如何判断它是否是平衡二叉树?解答:要判断一个二叉树是否是平衡二叉树,我们可以使用递归的方式。
对于每个节点,我们分别计算其左子树和右子树的高度差,如果高度差大于1,则该二叉树不是平衡二叉树。
具体实现时,我们可以定义一个递归函数,该函数接收一个节点作为参数,并返回以该节点为根节点的子树的高度。
在递归函数中,我们先判断节点是否为空,如果为空则返回0;否则,我们分别计算左子树和右子树的高度,然后取两者中的较大值加1作为当前节点的高度。
最后,我们判断左子树和右子树的高度差是否大于1,如果大于1,则该二叉树不是平衡二叉树。
数据结构第七章习题答案
第七章图
1.下面是一个图的邻接表结构,画出此图,并根据此存储结构和深度优先搜索
算法写出从C开始的深度优先搜索序列。
0A13^
1B35^
2C30^
3D4^
4E^
5F4^
【解答】
A B F
C D E
C开始的深度优先搜索序列:CDEABF(唯一的结果)
2.假定要在某县所辖六个镇(含县城)之间修公路,若镇I和镇J之间有可能通
过道路连接,则Wij表示这条路的长度。
要求每个镇都通公路且所修公路总里程
最短,那么应选择哪些线路来修。
I11112233445 J23564546566 W ij1239102626474
(1).画出该图。
(2).用C语言描述该图的数组表示法存储结构,并注明你所使用变量的实际含义。
(3).图示你所定义的数据结构。
(4).标识出你选择的线路。
【解答】
(1)
(2)
#define MAX 6
char vexs[MAX];
出该图的所有强连通分量。
(2).在图中删除弧<2,1>,然后写出从顶点1开始的拓扑有序序列。
【解答】
(1) 共4个强连通分量:
(2) 1,3,2,6,5,4
5 4
6 1 3 2
4
15 10
2
15 20 30 4 10
10。
《数据结构(C语言版 第2版)》(严蔚敏 著)第七章练习题答案
《数据结构(C语言版第2版)》(严蔚敏著)第七章练习题答案第7章查找1.选择题(1)对n个元素的表做顺序查找时,若查找每个元素的概率相同,则平均查找长度为()。
A.(n-1)/2B.n/2C.(n+1)/2D.n答案:C解释:总查找次数N=1+2+3+…+n=n(n+1)/2,则平均查找长度为N/n=(n+1)/2。
(2)适用于折半查找的表的存储方式及元素排列要求为()。
A.链接方式存储,元素无序B.链接方式存储,元素有序C.顺序方式存储,元素无序D.顺序方式存储,元素有序答案:D解释:折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
(3)如果要求一个线性表既能较快的查找,又能适应动态变化的要求,最好采用()查找法。
A.顺序查找B.折半查找C.分块查找D.哈希查找答案:C解释:分块查找的优点是:在表中插入和删除数据元素时,只要找到该元素对应的块,就可以在该块内进行插入和删除运算。
由于块内是无序的,故插入和删除比较容易,无需进行大量移动。
如果线性表既要快速查找又经常动态变化,则可采用分块查找。
(4)折半查找有序表(4,6,10,12,20,30,50,70,88,100)。
若查找表中元素58,则它将依次与表中()比较大小,查找结果是失败。
A.20,70,30,50B.30,88,70,50C.20,50D.30,88,50答案:A解释:表中共10个元素,第一次取⎣(1+10)/2⎦=5,与第五个元素20比较,58大于20,再取⎣(6+10)/2⎦=8,与第八个元素70比较,依次类推再与30、50比较,最终查找失败。
(5)对22个记录的有序表作折半查找,当查找失败时,至少需要比较()次关键字。
A.3B.4C.5D.6答案:B解释:22个记录的有序表,其折半查找的判定树深度为⎣log222⎦+1=5,且该判定树不是满二叉树,即查找失败时至多比较5次,至少比较4次。
(6)折半搜索与二叉排序树的时间性能()。
数据结构 习题 第七章 图 答案
第7章图二.判断题部分答案解释如下。
2. 不一定是连通图,可能有若干连通分量 11. 对称矩阵可存储上(下)三角矩阵14.只有有向完全图的邻接矩阵是对称的 16. 邻接矩阵中元素值可以存储权值21. 只有无向连通图才有生成树 22. 最小生成树不唯一,但最小生成树上权值之和相等26. 是自由树,即根结点不确定35. 对有向无环图,拓扑排序成功;否则,图中有环,不能说算法不适合。
42. AOV网是用顶点代表活动,弧表示活动间的优先关系的有向图,叫顶点表示活动的网。
45. 能求出关键路径的AOE网一定是有向无环图46. 只有该关键活动为各关键路径所共有,且减少它尚不能改变关键路径的前提下,才可缩短工期。
48.按着定义,AOE网中关键路径是从“源点”到“汇点”路径长度最长的路径。
自然,关键路径上活动的时间延长多少,整个工程的时间也就随之延长多少。
三.填空题1.有n个顶点,n-1条边的无向连通图2.有向图的极大强连通子图3. 生成树9. 2(n-1) 10. N-1 11. n-1 12. n 13. N-1 14. n15. N16. 3 17. 2(N-1) 18. 度出度 19. 第I列非零元素个数 20.n 2e21.(1)查找顶点的邻接点的过程 (2)O(n+e) (3)O(n+e) (4)访问顶点的顺序不同 (5)队列和栈22. 深度优先 23.宽度优先遍历 24.队列25.因未给出存储结构,答案不唯一。
本题按邻接表存储结构,邻接点按字典序排列。
25题(1) 25题(2) 26.普里姆(prim )算法和克鲁斯卡尔(Kruskal )算法 27.克鲁斯卡尔28.边稠密 边稀疏 29. O(eloge ) 边稀疏 30.O(n 2) O(eloge) 31.(1)(V i ,V j )边上的权值 都大的数 (2)1 负值 (3)为负 边32.(1)n-1 (2)普里姆 (3)最小生成树 33.不存在环 34.递增 负值 35.16036.O(n 2) 37. 50,经过中间顶点④ 38. 75 39.O(n+e )40.(1)活动 (2)活动间的优先关系 (3)事件 (4)活动 边上的权代表活动持续时间41.关键路径 42.(1)某项活动以自己为先决条件 (2)荒谬 (3)死循环 43.(1)零 (2)V k 度减1,若V k 入度己减到零,则V k 顶点入栈 (3)环44.(1)p<>nil (2)visited[v]=true (3)p=g[v].firstarc (4)p=p^.nextarc45.(1)g[0].vexdata=v (2)g[j].firstin (3)g[j].firstin (4)g[i].firstout (5)g[i].firstout (6)p^.vexj (7)g[i].firstout (8)p:=p^.nexti (9)p<>nil (10)p^.vexj=j(11)firstadj(g,v 0) (12)not visited[w] (13)nextadj(g,v 0,w)46.(1)0 (2)j (3)i (4)0 (5)indegree[i]==0 (6)[vex][i] (7)k==1 (8)indegree[i]==047.(1)p^.link:=ch[u ].head (2)ch[u ].head:=p (3)top<>0 (4)j:=top (5)top:=ch[j].count(6)t:=t^.link48.(1)V1 V4 V3 V6 V2 V5(尽管图以邻接表为存储结构,但因没规定邻接点的排列,所以结果是不唯一的。
(完整word版)数据结构 第七章图:习题
0 10 ∞ ∞
15 0 6 ∞
3 ∞ 0 4
∞ 8 2 0
(2)采用弗洛伊德算法求最短路径的过程如下:
7.对于有向无环图,
(1)叙述求拓扑有序序列的步骤。
(2)对于题图7-6所示的有向图,写出它的4个不同的拓扑有序序列。
【解答】(1)参见7.6节的介绍。
(2)它的4个不同的拓扑有序序列是:12345678,12354678,12347856,12347568。
(6)在V-S中找出最近的顶点5,加入S中,即s口={l,3,2,6,4,5}。此时S中包含了图的所有顶点,算法结束。最终dist[]={0,19,15,29,29,25),path[]={1,3,l,6,2, 3}。
由此得到:
从顶点1到顶点2的最短路径长度为:19 最短路径为:2<-3<-1
从顶点l到顶点3的最短路径长度为:15 最短路径为:3<-1
dist[4]=min{dist[4], dist[6]+cost[6][4])=min{∞..,25+4}=29,
则有dist[]={0, 19, 15, 29, 29, 25}, path[]={l,3,1,6,2,3}。
(5)在V-S中找出最近的顶点4,加入S中,即s[]:{l,3,2,6,4},并重新计算顶点l到达顶点5的距离,此时不需要修改dist值,则有dist[]={0,19,15,29,29,25),path[]={l,3, l,6,2, 3}。
(1)有n个顶点的无向连通图最多需要多少条边?最少需要多少条边?
(2)表示一个具有1000个顶点、1000条边的无向图的邻接矩阵有多少个矩阵元素?有多少非零元素?是否为稀疏矩阵?
数据结构第7章-答案
一、单选题C01、在一个图中,所有顶点的度数之和等于图的边数的倍。
A)1/2 B)1 C)2 D)4B02、在一个有向图中,所有顶点的入度之和等于所有顶点的出度之和的倍。
A)1/2 B)1 C)2 D)4B03、有8个结点的无向图最多有条边。
A)14 B)28 C)56 D)112C04、有8个结点的无向连通图最少有条边。
A)5 B)6 C)7 D)8C05、有8个结点的有向完全图有条边。
A)14 B)28 C)56 D)112B06、用邻接表表示图进行广度优先遍历时,通常是采用来实现算法的。
A)栈 B)队列 C)树 D)图A07、用邻接表表示图进行深度优先遍历时,通常是采用来实现算法的。
A)栈 B)队列 C)树 D)图A08、一个含n个顶点和e条弧的有向图以邻接矩阵表示法为存储结构,则计算该有向图中某个顶点出度的时间复杂度为。
A)O(n) B)O(e) C)O(n+e) D)O(n2)C09、已知图的邻接矩阵,根据算法思想,则从顶点0出发按深度优先遍历的结点序列是。
A)0 2 4 3 1 5 6 B)0 1 3 6 5 4 2 C)0 1 3 4 2 5 6 D)0 3 6 1 5 4 2B10、已知图的邻接矩阵同上题,根据算法,则从顶点0出发,按广度优先遍历的结点序列是。
A)0 2 4 3 6 5 1 B)0 1 2 3 4 6 5 C)0 4 2 3 1 5 6 D)0 1 3 4 2 5 6D11、已知图的邻接表如下所示,根据算法,则从顶点0出发按深度优先遍历的结点序列是。
A)0 1 3 2 B)0 2 3 1 C)0 3 2 1 D)0 1 2 3A12、已知图的邻接表如下所示,根据算法,则从顶点0出发按广度优先遍历的结点序列是。
A)0 3 2 1 B)0 1 2 3 C)0 1 3 2 D)0 3 1 2A13、图的深度优先遍历类似于二叉树的。
A)先序遍历 B)中序遍历 C)后序遍历 D)层次遍历D14、图的广度优先遍历类似于二叉树的。
数据结构第七章习题课
1、判定一个有向图是否存在回路,除了利用拓扑排序方法外,还可以利用( )A 、求关键路径的方法B 、求最短路径的Dijkstra 方法C 、宽度优先遍历算法D 、深度优先遍历算法 2.图中有关路径的定义是( )oA. 由顶点和相邻顶点序偶构成的边所形成的序列B. 由不同顶点所形成的序列C. 由不同边所形成的序列D.上述定义都不是3. 一个n 个顶点的连通无向图,其边的个数至少为()4. 当一个有N 个顶点的无向图用邻接矩阵 A 表示时,顶点Vi 的度是()5. 下列说法不正确的是( )oA. 图的遍历是从给定的源点出发每一个顶点仅被访问一次B. 遍历的基本算法有两种:深度遍历和广度遍历C. 图的深度遍历不适用于有向图D. 图的深度遍历是一个递归过程6. 无向图 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)},对该图进行深度优先遍历,得到的顶点序 列正确的是( )oA . a,b,e,c,d,fB . a,c,f,e,b,dC . a,e,b,c,f,dD . a,e,d,f,c,b 7. 设图如右所示,在下面的5个序列中,符合深度优先遍历的序列有多少?(a e d f cb a e f dc b C . 3个&在图采用邻接表存储时,求最小生成树的A. O (n ) B O (n+e ) 9.已知有向图 G=(V,E),其中 V={V 1,V 2,V 3,V 4,V 5,V 6,V 7},E={VV 1,V 2>,VV 1,V 3>,VV 1,V 4>,VV 2,V 5>,VV 3,V 5>,VV 3,V 6>,VV 4,V 6>,VV 5,V 7>,VV 6,V 7>},A . n-1B . nC . n+1D . nlogn ;nZ A[i, j]A. i 4nZ A 【,j]B. 订nZ A[j,i]C . VnnS A[i, j]迟 Aj,i]D. v + vPrim 算法的时间复杂度为(23C. O (n )D. O (n ) )oa eb d f cB . 4个G 的拓扑序列是()。
数据结构 第7章答案(已核 )
7.6习题一、名词解释(1)主关键字(2)平均查找长度(3)静态查找表(4)动态查找表(5)二叉查找树(6)哈希表二、填空题(1)静态查找表的存储结构主要采用顺序存储结构,如果需要,也可以采用链式存储结构,但当使用二分(折半)查找算法或(斐波那契数列)查找算法来查找时,要求查找表只能是顺序存储结构,并且查找表中的数据序列必须有序。
(2)通过中根序遍历一棵二叉查找树得到的数据序列必然是一个非降序(有序)序列。
(3)各种查找方法中,平均查找长度与结点个数n无关的查找方法是哈希查找。
*(4)如果对一个有序查找表SST进行折半查找,在最坏时要比较10次,那么对该查找表进行顺序查找时,在最坏时要比较210 -1 次。
解析:最坏情况要比较10次,说明树的高度是10。
而一棵深度为10的二叉树,最多有210 -1个结点。
*(5)深度为7的平衡二叉树至少有33 个结点。
解析:在节点最少的情况下,左右子树的高度差为1,则总节点数S(n)=S(n-1)+S(n-2)+1。
已知,初始值S(1) = 1,S(2) = 2,可以推出:S(3) = 4S(4) = 7S(5) = 12S(6) = 20S(7) = 33所以,高度为7的平制衡二百叉树最少结点数是33。
假设深度为n的平衡二叉树至少有F(n)个结点,那么F(n)满足F(n)=F(n-1)+F(n-2)+1。
三、简答题(1)请画出长度为8的有序查找表的折半查找判定树。
(2)折半查找的前提:顺序存储、查找表有序。
(3)已知关键字序列为{45,28,67,33,29,50},二叉排序树初始为空,要求:①画出按正向(从关键字45开始)顺序插入结点建立的二叉排序树。
②画出按反向(从关键字50开始)顺序插入结点建立的二叉排序树。
(4)二叉排序树的平均查找长度:与结点个数和树的形态有关。
(5)设哈希表的地址空间为0~6,哈希函数H(key)=key % 7。
请对关键字序列{32,13,49,18,22,38}按线性探测再散列处理冲突的方法构造哈希表。
数据结构与算法(C语言篇)第7章 习题答案[2页]
习题答案1.思考题(1)首先采用循环的方式对单向循环链表进行遍历,然后寻找需要删除元素的上一个元素与下一个元素,最后将这两个元素进行连接,即可实现指定元素的删除。
每一次删除元素,单向循环链表都会重新连接为一个新的环。
然后继续指定元素进行删除,重复步骤,直到环中的元素全部删除完为止。
(2)回溯法,即确定了解空间的组织结构后,就可以从开始结点开始,以深度优先的方式对整个解空间进行搜索。
这个开始的结点就成为活结点,同时也是当前的扩展结点。
在此结点向下进行纵深搜索移动的一个新的结点,那么这个新借贷就会成为新的活结点和拓展结点,但是如果当前的扩展结点不能再向纵深移动,那么此活结点就会变为死结点,此时就要进行回溯移动,移动到最近的活结点,并将此活结点变为当前的扩展结点。
这就是回溯的工作方式,也是其工作的基本思想。
(3)动态规划法与分治法类似,其基本的思想是将规模较大的问题分解为较小的子问题,先求解子问题,然后通过这些子问题的解得到原问题的解,但是与分治法不同的是,经过分解后得到的子问题之间并不是相互独立的。
为了达到这一目的,可以用一个表来记录所有已经解决的子问题,这样不管计算过的子问题的答案在后面的求解过程中是否被用到都会被记录,这就是动态规划法的思想。
4.编程题(1)1int g[N][N] //表示无向图对应的矩阵2#define M (1 << (N-1))34int dp[N][M];56void TSP(){7 //初始化dp[i][0]8 int i = 0, j, k;9 for(i = 0; i < N; i++){10 dp[i][0] = g[i][0];11 }12 //求解dp[i][j],先更新列再更新行13 for(j = 1; j < M; j++){14 for(i = 0; i < N; i++){15 dp[i][j] = INF;16 //如果集合j(或状态j)中包含顶点i,则不符合条件退出17 //判断方法为:判断j对应的二进制数的第i位是否为118 if(((j >> (i - 1)) & 1) == 1){19 continue;20 }21 for(k = 1; k < N; k++){22 //跳过不合理的路径选择23 if(((j >> (k - 1)) & 1) == 0){24 continue;25 }26 //更新dp[i][j]的值27 //计算从i开始经过状态j回到起始点的最短距离28 if(dp[i][j] > g[i][k] + dp[k][j ^ (1 << (k - 1))]){29 dp[i][j] = g[i][k] + dp[k][j ^ (1 << (k - 1))];30 }31 }32 }33 }34}35。
数据结构教程 李春葆 七章习题答案
//在下标为i的前面的数组中寻找两个权值最小的节点,作为孩子节点
for(j = 0; j<i; j++)
{
if(-1==ht[j].parent)
{
if(min1>ht[j].weight)
{
min2 = min1; //至于为什么有这句和下面的一句,,大家依次将权值假设为2 1 3带入里面自己手工模仿运行
设计;狼影
时间:2012.10.5
***************************************/
/******************************************************
若发现错误请 留言本空间,万分感谢!!
/*******************/
-------------------------------------------------------------
权值: 2 3 4 7 8 9 5 9 15 18 33
-------------------------------------------------------------
}
/*************************************************************
输入叶子节点的个数
6
输入6个叶子的权值
2 3 4 7 8 9
哈夫曼树顺序存储如下
-------------------------------------------------------------
{
int i;
printf("\n-------------------------------------------------------------\n");
数据结构复习题参考答案
数据结构总复习第一部分课后习题第一章课后习题P16 1、2、5、6、9第三章课后习题P66 2、3第四章课后习题P88 1第五章课后习题P102 1、2第六章课后习题P134-135 1、3、16、18完成P137 实验二构造哈夫曼编码第七章课后习题P177 1、2、4、8、10第二部分综合习题一、单项选择题1.如果在数据结构中每个数据元素只可能有一个直接前驱,但可以有多个直接后继,则该结构是(C )A. 栈B. 队列C. 树D. 图2.下面程序段的时间复杂度为(B )for (i=0; i<m; i++)for (j=0; j<n; j++)A[i][j]=i*j;A. O (m2)B. O (n2)C. O (m*n)D. O (m+n)3.在头指针为head的非空单循环链表中,指针p指向尾结点,下列关系成立的是( A )A. p->next==headB. p->next->next==headC. p->next==NULLD. p==head4.若以S和X分别表示进栈和退栈操作,则对初始状态为空的栈可以进行的栈操作系列是( D )A. SXSSXXXXB. SXXSXSSXC. SXSXXSSXD. SSSXXSXX5.两个字符串相等的条件是(D )A. 串的长度相等B. 含有相同的字符集C. 都是非空串D. 串的长度相等且对应的字符相同6.已知一棵含50个结点的二叉树中只有一个叶子结点,则该树中度为1的结点个数为( D )A. 0B. 1C. 48D. 497.算法分析的目的是:(C )(A)找出数据结构的合理性(B)研究算法中输入和输出的关系(C)分析算法的效率以求改进(D)分析算法的易懂性和文档性8.用链表表示线性表的优点是:( C )(A)便于随机存取(B)花费的存储空间比顺序表少(C)便于插入和删除(D)数据元素的物理顺序与逻辑顺序相同9.在数组表示的循环队列中,front、rear分别为队列的头、尾指针,maxsize为数组的最大长度,队满的条件是:( D )(A)front=rear (B)rear=maxsize(C)rear=front (D)(rear+1)%maxsize=front10.若已知一棵二叉树先序序列为ABCDEFG,中序序列为CBDAEGF,则其后序序列为:( A )(A)CDBGFEA (B)CDBFGEA(C)CDBAGFE (D)BCDAGFE11.执行下列程序段,执行S的次数(S这段程序的时间复杂度)是:(D )for(int i=1;i<=n;i++)for(int j=1;j<=i;j++)S;(A)n2 (B)n2/2 (C)n(n+1) (D)n(n+1)/212.以下数据结构中哪一个是非线性结构的是:( D )(A)队列(B)栈(C)线性表(D)图13.设有6个结点的无向图,该图至少有多少条边才能确保是一个连通图:(A )(A)5 (B)6 (C)7 (D)814.树形结构数据元素之间的关系是:( C )(A)一对一关系(B)多对多关系(C)一对多关系(D)多对一关系15.一个栈的入栈序列是a,b,c,d,e,则栈的不可能的输出序列是:( C )(A)edcba (B)decba (C)dceab (D)abcde16.静态查找和动态查找的根本区别在于:(B )(A)它们的逻辑结构不一样(B)施加在其上的操作不同(C)所包含的数据元素的类型不一样(D)存储的实现不一样17.关键路径是AOE网中:(A )(A)从源点到终点的最长路径(B)从源点到终点的最短路径(C)最长的回路(D)最短的回路18.采用折半查找方法进行查找,数据文件为,且限于;(A )(A)有序表顺序存储结构(B)有序表链式存储结构(C)随机表顺序存储结构(D)随机表链式存储结构19.一个高度为h的完全二叉树共有n个结点,其中m个叶子结点,则下列式子成立的是( D )(A)n=h+m (B)h+m=2n (C)m=h-1 (D)n=2m-120.下列说法中不正确的是:(C )(A)数组时一种线性结构(B)数组是一种定长的线性结构(C)除了插入和删除操作外,数组的基本操作还有存取、修改、检索和排序等(D)数组的基本操作有存取、修改、检索和排序等,没有插入与删除操作21.设无向图G有n个顶点e条边,则该无向图中所有顶点的度之和为:( D )(A)n (B)e (C)2n (D)2e22.对下面的无向图进行广度优先搜索后所得到的顶点访问序列,正确的是:(A )(A)ABDEFC (B)ABFEDC (C)ADCBEF (D)ADCBFE23.若某线性表中最常用的操作是取第i 个元素和找第i个元素的前趋元素,则采用( D )存储方式最节省时间。
数据结构第7章树和二叉树习题课PPT课件
(3)画出二叉树bt的后序线索
a
化树。
b
cd
ef g
hi
j
(3)画出二叉树bt的后序线索 化树。
后序序列
ec hf j i g dba
a
b
cd
ef g
hi
j
(3)画出二叉树bt的后序线索 化树。
0
后序序列 ec hf j i g dba
0a 1
∧
0b 0
root
1
0c1
∧
0 d0
1e1
∧∧
0f1
补1 T={(a,2),(b,3),(c,4),(d,7),(e,9)}为带权字符集, 试构造关于该字符集的一颗哈夫曼树,求其加权路 径长度WPL、T中每个字符的哈曼夫编码和哈夫曼 编码的平均长度。
2 3479
补1 T={(a,2),(b,3),(c,4),(d,7),(e,9)}为带权字符集, 试构造关于该字符集的一颗哈夫曼树,求其加权路 径长度WPL、T中每个字符的哈曼夫编码和哈夫曼 编码的平均长度。
99 45
23
7.3 给定权值集w={2,3,4,7,8,9},试构造关于w 的的一颗哈夫曼树,并求其带权路径长度WPL。
15
78
18 99
45
23
7.3 给定权值集w={2,3,4,7,8,9},试构造关于w 的的一颗哈夫曼树,并求其带权路径长度WPL。
33
15
78
18 99
45
23
WPL=(2+3)×4+4×3+9× 2+(7+8)× 2 =80
(2)写出按先序、中序和后
a
序遍历二叉树bt所得到的结点
数据结构第七章课后习题答案
7_1对于图题7.1(P235)的无向图,给出:(1)表示该图的邻接矩阵。
(2)表示该图的邻接表。
(3)图中每个顶点的度。
解:(1)邻接矩阵:0111000100110010010101110111010100100110010001110(2)邻接表:1:2----3----4----NULL;2: 1----4----5----NULL;3: 1----4----6----NULL;4: 1----2----3----5----6----7----NULL;5: 2----4----7----NULL;6: 3----4----7----NULL;7: 4----5----6----NULL;(3)图中每个顶点的度分别为:3,3,3,6,3,3,3。
7_2对于图题7.1的无向图,给出:(1)从顶点1出发,按深度优先搜索法遍历图时所得到的顶点序(2)从顶点1出发,按广度优先法搜索法遍历图时所得到的顶点序列。
(1)DFS法:存储结构:本题采用邻接表作为图的存储结构,邻接表中的各个链表的结点形式由类型L_NODE规定,而各个链表的头指针存放在数组head中。
数组e中的元素e[0],e[1],…..,e[m-1]给出图中的m条边,e中结点形式由类型E_NODE规定。
visit[i]数组用来表示顶点i是否被访问过。
遍历前置visit各元素为0,若顶点i被访问过,则置visit[i]为1.算法分析:首先访问出发顶点v.接着,选择一个与v相邻接且未被访问过的的顶点w访问之,再从w 开始进行深度优先搜索。
每当到达一个其所有相邻接的顶点都被访问过的顶点,就从最后访问的顶点开始,依次退回到尚有邻接顶点未曾访问过的顶点u,并从u开始进行深度优先搜索。
这个过程进行到所有顶点都被访问过,或从任何一个已访问过的顶点出发,再也无法到达未曾访问过的顶点,则搜索过程就结束。
另一方面,先建立一个相应的具有n个顶点,m条边的无向图的邻接表。
数据结构第三版第七章作业参考答案
else { t=(BTNode *)malloc(sizeof(BTNode));
t->data=b->data; t1=Swap(b->lchild); t2=Swap(b->rchild); t->lchild=t2; t->rchild=t1; } return t; }
}
7.7 假设二叉树采用二叉链存储结构,t 指向根结点,p 所指结点为任一给 定的结点,设 计一个算法,输出从根结点到p 所指结点之间路径。
解:本题可以采用《教程》中例 7.8 的方法(只需对该算法作简单修改即
可
)
。
这
里
介
绍另一种方法,即非递归后序遍历树t(参见《教程》7.4.3 小节后序遍历非
递
归
二叉树树 形表示。
答:由《教程》7.6 节的构造算法得到的二叉树的构造过程和二叉树如图 7.3 所示。
b 左:c 右:ed
a 左:cbed 右:hgijf
f 左:hgij 右:空
c 左:空 右:空
d
g
左:e
左:h
右:空 右:ij
e 左:空 右:空
h 左:空 右:空
i 左:空 右:j
j 左:空 右:空
图 7.3 二叉树的构造过程
7.3 设给定权集 w={2,3,4,7,8,9},试构造关于 w 的一棵哈夫曼树,并求其带权 路径长度 WPL。
答:本题的哈夫曼树如图 7.4 所示。
33
18
15
9
97
8
5
4
2
3
图 7.4 一棵哈夫曼树
其带权路径长度WPL=(9+7+8)×2+4×3+(2+3)×4=80。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、判定一个有向图是否存在回路,除了利用拓扑排序方法外,还可以利用()。
A、求关键路径的方法B、求最短路径的Dijkstra方法C、宽度优先遍历算法D、深度优先遍历算法2.图中有关路径的定义是()。
A.由顶点和相邻顶点序偶构成的边所形成的序列B.由不同顶点所形成的序列C.由不同边所形成的序列D.上述定义都不是3.一个n个顶点的连通无向图,其边的个数至少为()。
A.n-1 B.n C.n+1 D.nlogn;4.当一个有N个顶点的无向图用邻接矩阵A表示时,顶点Vi的度是()。
A.∑=nijiA1],[B.[]∑=n1jj,iAC.∑=nii jA1],[D.∑=nijiA1],[+[]∑=n1ji,jA5. 下列说法不正确的是()。
A.图的遍历是从给定的源点出发每一个顶点仅被访问一次B.遍历的基本算法有两种:深度遍历和广度遍历C.图的深度遍历不适用于有向图D.图的深度遍历是一个递归过程6.无向图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,b7. 设图如右所示,在下面的5个序列中,符合深度优先遍历的序列有多少?()a eb d fc a c fde b a e df c b a e f d c b a e f d b cA B.4个C.3个D.2个8. 在图采用邻接表存储时,求最小生成树的Prim 算法的时间复杂度为( )。
A. O(n)B. O(n+e)C. O(n2)D. O(n3)9.已知有向图G=(V,E),其中V={V1,V2,V3,V4,V5,V6,V7},E={<V1,V2>,<V1,V3>,<V1,V4>,<V2,V5>,<V3,V5>,<V3,V6>,<V4,V6>,<V5,V7>,<V6,V7>},G的拓扑序列是()。
A.V1,V3,V4,V6,V2,V5,V7B.V1,V3,V2,V6,V4,V5,V7C.V1,V3,V4,V5,V2,V6,V7D.V1,V2,V5,V3,V4,V6,V710.若一个有向图的邻接矩阵中,主对角线以下的元素均为零,则该图的拓扑有序序列()。
A.存在B.不存在11.一个有向无环图的拓扑排序序列()是唯一的。
A.一定B.不一定12.在有向图G的拓扑序列中,若顶点Vi在顶点Vj之前,则下列情形不可能出现的是()。
A.G中有弧<Vi,Vj> B.G中有一条从Vi到Vj的路径C.G中没有弧<Vi,Vj> D.G中有一条从Vj到Vi的路径13.下列关于AOE网的叙述中,不正确的是()。
A.关键活动不按期完成就会影响整个工程的完成时间B.任何一个关键活动提前完成,那么整个工程将会提前完成C.所有的关键活动提前完成,那么整个工程将会提前完成D.某些关键活动提前完成,那么整个工程将会提前完成14.判断一个无向图是一棵树的条件是______。
答:有n个顶点,n-1条边的无向连通图15.有向图G的强连通分量是指______。
答:有向图的极大强连通子图16. 设无向图G 有n 个顶点和e 条边,每个顶点Vi 的度为di(1<=i<=n),则e=______答:(d1+d2+……+dn)/217. 在有n个顶点的有向图中,若要使任意两点间可以互相到达,则至少需要______条弧。
答:n18.在有n个顶点的有向图中,每个顶点的度最大可达______。
答:2(n-1)19.右图中的强连通分量的个数为(答:320.N个顶点的连通图用邻接矩阵表示时,该矩阵至少有_______个非零元素。
答:2(N-1)21.在有向图的邻接矩阵表示中,计算第I个顶点入度的方法是______。
答:第I列非零元素个数22. 已知一无向图G=(V,E),其中V={a,b,c,d,e } E={(a,b),(a,d),(a,c),(d,c),(b,e)}现用某一种图遍历方法从顶点a开始遍历图,得到的序列为abecd,则采用的是______遍历方法。
答:深度优先23. 为了实现图的广度优先搜索,除了一个标志数组标志已访问的图的结点外,还需______存放被访问的结点以实现遍历。
答:队列24. 有一个用于n个顶点连通带权无向图的算法描述如下:(1).设集合T1与T2,初始均为空;(2).在连通图上任选一点加入T1;(3).以下步骤重复n-1次:a.在i属于T1,j不属于T1的边中选最小权的边;b.该边加入T2。
上述算法完成后,T2中共有______条边,该算法称______算法,T2中的边构成图的______。
答:(1)n-1 (2)普里姆(3)最小生成树25.有向图G可拓扑排序的判别条件是______。
答:不存在环26.有向图G=(V,E),其中V(G)={0,1,2,3,4,5},用<a,b,d>三元组表示弧<a,b>及弧上的权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的最短路径长度是______,经过的中间顶点是______。
答:50,经过中间顶点427. 上面的图去掉有向弧看成无向图则对应的最小生成树的边权之和为______。
答:7528.AOV网中,结点表示______,边表示______。
AOE网中,结点表示______,边表示______。
答:(1)活动(2)活动间的优先关系(3)事件(4)活动,边上的权代表活动持续时间29. 当一个AOV网用邻接表表示时,可按下列方法进行拓扑排序。
(1).查邻接表中入度为______的顶点,并进栈;(2).若栈不空,则①输出栈顶元素Vj,并退栈;②查Vj的直接后继Vk,对Vk 入度处理,处理方法是______;(3).若栈空时,输出顶点数小于图的顶点数,说明有______,否则拓扑排序完成。
答:(1)零 (2)V k 度减1,若V k 入度己减到零,则V k 顶点入栈 (3)环30.首先将如下图所示的无向图给出其存储结构的邻接链表表示,然后写出对其分别进行深度,广度优先遍历的结果。
31.已知某图的邻接表为 (1).写出此邻接表对应的邻接矩阵;(2).写出由v1开始的深度优先遍历的序列;(3).写出由v1开始的深度优先的生成树;(4).写出由v1开始的广度优先遍历的序列;(5).写出由v1开始的广度优先的生成树;(6).写出将无向图的邻接表转换成邻接矩阵的算法。
32.考虑右图: (1)从顶点A 出发,求它的深度优先生成树 (2)从顶点E 出发,求它的广度优先生成树(3)根据普利姆(Prim) 算法,从顶点A 出发,求它的最小生成树答:设该图用邻接表存储结构存储,顶点的邻接点按顶点编号升序排列(1)ABGFDEC (2)EACFBDG(3)E A B G C DF 5 3 6 1 4 1 3 2 533.已知一个无向图如下图所示,要求分别用Prim 和Kruskal 算法生成最小树(假设以①为起点,试画出构造过程)。
34.G=(V ,E)是一个带有权的连通图,(1).请回答什么是G (2).G 为下图所示,请找出G35.一带权无向图的邻接矩阵如下图 ,试画出它的一棵最小生成树。
36.请看下边的无向加权图。
(1).写出它的邻接矩阵(2).按Prim 算法求其最小生成树,并给出构造最小生成树过程中辅助数组的各分量值。
37.下图所示是一带权有向图的邻接表法存储表示。
其中出边表中的每个结点均含有三个字段,依次为边的另一个顶点在顶点表中的序号、边上的权值和指向下一个边结点的指针。
试求:(1).该带权有向图的图形;(2).从顶点V1为起点的广度优先周游的顶点序列及对应的生成树(即支撑树);(3).以顶点V1为起点的深度优先周游生成树;(4).由顶点V1到顶点V3的最短路径。
38.对于如下的加权有向图,给出算法Dijkstra 产生的最短路径的支撑树,设顶点A 为源点,并写出生成过程。
(1).以顶点V1为出发点的唯一的深度优先遍历;(2).以顶点V1为出发点的唯一的广度优先遍历;(3).该图唯一的拓扑有序序列。
123456(顶点边)(出边表)214540.对图示的AOE网络,计算各活动弧的e(a i)和l(a i)的函数值,各事件(顶点)的ve(Vj)和vl (Vj)的函数值,列出各条关键路径。
41.设有向G图有n个点(用1,2,…,n表示),e条边,写一算法根据其邻接表生成其反向邻接表,要求算法复杂性为O(n+e)。
void InvertAdjList(AdjList gin,gout)//将有向图的出度邻接表改为按入度建立的逆邻接表{for (i=1;i<=n;i++)//设有向图有n个顶点,建逆邻接表的顶点向量。
{gin[i].vertex=gout[i].vertex; gin.firstarc=null; }for (i=1;i<=n;i++) //邻接表转为逆邻接表。
{p=gout[i].firstarc;//取指向邻接表的指针。
while (p!=null){ j=p->adjvex;s=(ArcNode *)malloc(sizeof(ArcNode));//申请结点空间。
s->adjvex=i; s->next=gin[j].firstarc; gin[j].firstarc=s;p=p->next;//下一个邻接点。
}//while}//for }42.写出从图的邻接表表示转换成邻接矩阵表示的算法。
void AdjListToAdjMatrix(AdjList gl, AdjMatrix gm)//将图的邻接表表示转换为邻接矩阵表示。
{for (i=1;i<=n;i++) //设图有n个顶点,邻接矩阵初始化。
for (j=1;j<=n;j++) gm[i][j]=0;for (i=1;i<=n;i++){p=gl[i].firstarc; //取第一个邻接点。
while (p!=null) {gm[i][p->adjvex]=1;p=p->next; }//下一个邻接点}//for }//算法结束43.设已给出图的邻接矩阵,要求将邻接矩阵转换为邻接表。