(1)G 是一个非连通无向图,共有 28 条边,则该图至少有( C)
个顶点
A.7 B.8 C.9 D.10
8个顶点的无向图最多有 8*7/2=28 条边,再添加一个点即构
成非连通无向图,故至少有 9 个顶点
(2)分别以邻接矩阵和邻接表作为存储结构,实现以下图的基本操
作:
① 增加一个新顶点 v,InsertVex(G, v);
② 删除顶点 v 及其相关的边,DeleteVex(G, v);
③ 增加一条边<v,w>,InsertArc(G, v, w);
④ 删除一条边<v,w>,DeleteArc(G, v, w)
①增加一条边
`Status 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[j].adj) { G.arcs[j].adj=1; G.arcnum++; } return ok;}` `///----删除顶点V及其相关的边----- Status Delete_vex(MGraph &G,char v)//在邻接矩阵表示的图上删除顶点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.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; }`
(3)一个连通图采用邻接表作为存储结构,设计一个算法,实现从
顶点 v 出发的深度优先遍历的非递归过程.
`Void DFSn(Graph G,int v) { //从第 v 个顶点出发非递归实现深度优先遍历图 G Stack s; SetEmpty(s); Push(s,v); While(!StackEmpty(s)) { //栈空时第 v 个顶点所在的连通分量已遍历完 Pop(s,k); If(!visited[k]) { visited[k]=TRUE; VisitFunc(k); //访问第 k 个顶点 //将第 k 个顶点的所有邻接点进栈 for(w=FirstAdjVex(G,k);w;w=NextAdjVex(G,k,w)) { if(!visited[w]&&w!=GetTop(s)) Push(s,w); //图中有环时 w==GetTop(s) } } }`
(4)设计一个算法,求图 G 中距离顶点 v 的最短路径长度最大的一
个顶点,设 v 可达其余各个顶点。
分析:利用 Dijkstra 算法求 v0 到其它所有顶点的最短路径,分别保存在
数组 D[i]中,然后求出 D[i]中值最大的数组下标 m 即可。
`int ShortestPath_MAX(AMGraph G, int v0) { //用 Dijkstra 算法求距离顶点 v0 的最短路径长度最大的一个顶点 m n=G.vexnum; //n 为 G 中顶点的个数 for(v = 0; v<n; ++v) { //n 个顶点依次初始化 S[v] = false; //S 初始为空集 D[v] = G.arcs[v0][v]; //将 v0 到各个终点的最短路径长度初始化 if(D[v]< MaxInt) Path [v]=v0;//如果 v0 和 v 之间有弧,则将 v 的前驱置为 v0 else Path [v]=-1; //如果 v0 和 v 之间无弧,则将 v 的前驱置为 -1; } S[v0]=true; //将 v0 加入 S D[v0]=0; //源点到源点的距离为0 /*开始主循环,每次求得 v0 到某个顶点 v 的最短路径,将 v加到 S 集*/ for(i=1;i<n; ++i){ //对其余 n− 1 个顶点,依次进行计算 min= MaxInt; for(w=0;w<n; ++w) if(!S[w]&&D[w]<min) {v=w; min=D[w];} //选择一条当前的最短路径,终点为 v S[v]=true; //将 v 加入 S for(w=0;w<n; ++w) //更新从 v0到 V− S 上所有顶点的最短路径长度 if(!S[w]&&(D[v]+G.arcs[v][w]<D[w])){ D[w]=D[v]+G.arcs[v][w]; //更新 D[w] Path [w]=v;//更改 w 的前驱为V } } /*最短路径求解完毕,设距离顶点 v0 的最短路径长度最大的一个顶点为 m */ Max=D[0]; m=0; for(i=1;i<n;i++) if(Max<D[i]) m=i; return m ;`
(5)采用邻接表存储结构,编写一个算法,判别无向图中任意给定的两个顶点之间是否存在一条长度为为 k 的简单路径
`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]=l; for(p=G.vertices[i].firstarc;p;p=p->nextarc) //链域(firstarc,nextarc),邻接点域(adjvex) {l=p->adjvex; if(!visited[l]) if(exist_path_len(G,l,j,k-1)) return 1; //剩余路径长度减一 } visited[i]=0; //本题允许曾经被访问过的结点出现在另一条路径中 }//else return 0; //没找到 }`