五、算法设计题
1.设计一个算法:对一个邻接表表示的含有n个顶点和e条弧的有向图G,求解每个顶点的度。
算法:
void vertexDegree(ALGraph G,int n;int e){
int i,j;
int indeg[n],outdeg[n],deg[n];//入度,出度,度
EdgeNode *p;
for(i=0;i<n;i++){
indeg[i]=0;
outdeg[i]=0;
deg[i]=0;
}//初始化各度数数组
for(i=0;i<n;i++){
p=G.vexs[i].firstedge;//让p作为第i个顶点指向的第一条边
while(p){
outdeg[i]+=1;//求第i个顶点的出度
j=p->adjvex;
inedg[j]+=1;//每条边指向的顶点的入度加一,最后就能得到全部入度
p=p->nextedge;
}
}
for(i=0;i<n;i++)
deg[i]=indeg[i]+outdeg[i];//顶点度数等于入度出度之和
}
2.设计一个算法:输出无向图中vi到vj的长度为length的所有简单路径。
算法:
//在调用时需要提前初始化flag数组全为0
void SimplePath(ALGraph G,int i,int j,int length,int *path,int *flag){
if(length==0){
if(i=j){
for(int k=0;k<length;k++)
cout<<path[k]<<" ";
cout<<j<<endl;
}
}//当length值减到0,且终点和起点相同时输出路径。
path[length-1]=i;//将当前顶点添加到路径中
flag[i]=1;//置当前顶点标志位为1
EdgeNode *p=G.vexs[i].firstedge;
while(p){
if(flag[p->adjvex]==0)
SimplePath(G,p->adjvex,j,length-1,path,flag)
//若p所指向的顶点没被访问过则递归寻找从顶点p->adjvex到j的长度为length-1的简单路径
p=p->nextedge;//接着查找i的下一个邻接点
}
flag[i]=0;//置flag为0方便递归时寻找下一条边
}
3.设计一个算法:将一个无向图的邻接矩阵转化为邻接表。
算法:
void Trans(MGraph G,ALGraph P){
for(int i=0;i<G.vexnum;i++)
P.vexs[i].vex=G.vexs[i];//将P的表头结点赋值
P.vexnum=G.vexnum;
P.edgenum=G.edgenum;//给P的顶点数和边数赋值
for(i=0;i<G.vexnum;i++){
P.vexs[i].firstedge=NULL;//初始化各链表
for(int j=0;j<G.vexnum;j++){
if(G.edges[i][j]==1){
EdgeNode *s=new EdgeNode;
s.adjvex=j;
s.nextedge=P.vexs[i].firstedge;
P.vexs[i].firstedge=s;
//若在第i行中第j个元素值为1,则用头插法插入第i个链表中
}
}
}
}
4.设计一个算法:基于深度优先遍历的算法,判断以邻接表存储的有向图是否存在由顶点vi到vj的路径(vi!=vj)。
算法:
int visited[Vertex_MAX];//全局变量,标记顶点是否被访问
bool hasPath(ALGraph G,int i,int j){//调用函数之前置visit全为零
EdgeNode *p=G.vexs[i].firstedge;
if(i==j)
return TRUE;//如果起点终点相同则代表有路径
visited[i]=1;//置顶点i被访问
while(p){
if(visited[p->adjvex]==0&&hasPath(G,p->adjvex,j))
return TRUE;//迭代调用深度遍历的点查看是否有路径
p=p->nextedge;//p指向下一条邻边
}
return FALSE;//如果遍历结束后没找到路径返回错误
}
5.设计一个算法:判断无向图G是否连通;如果连通则返回1;否则返回0。
代码:
int Connected(ALGraph G){
for(int i=0;i<G.vexnum;i++)
visit[i]==0;//初始化标志数组
DFS_ALG(G,0);//深度遍历G
for(i=0;i<G.vexnum;i++)
if(!visit[i])
return 0;//如果有点没被遍历到那么就不连通
return 1;//如果都遍历到了则连通
}