题目:试设计一个算法,判断一个无向图G是否为一棵树。若是一棵树,则返回true,否则返回false
关键字:图 ; 树的判断
思路:
判断一个图G是否为树的条件有两个:
1.G必须是无回路的连通图
(无回路的判断有:DFS;拓扑排序;求关键路径失败)
2.G是边为n-1的连通图
后者代码简单,因此本题选择后者作为思路。
首先,对连通的判定:
思路:用能否仅一次调用遍历搜索即可完成遍历全部顶点来判定。
实操:采用深度优先搜索算法在遍历图的过程中统计可能访问到的点个数和边的条数。若一次遍历就能访问n个顶点和n-1条边,则可断定此图是一棵树。
需要函数:一个包含了深度遍历搜索+统计顶点和边总数的函数DFS
需要变量:G,图;v顶点;Vnum顶点总数;Enum边总数
注:对于无向图而言,无论是邻接矩阵还是邻接表来存储图的顶点和边的所有信息,全部遍历过后,实际遍历过(此时应该看存储结构而非逻辑结构!)的顶点总数为N,边总数为2(N-1)
代码:
bool isTree(Graph G){
for(i=1;i<=G.vexnum;i++)
visited[i]=FALSE;//访问标记visited[]初始化
int Vnum=0;Enum=0;//记录顶点数和边数
DFS(G,1,Vnum,Enum,visited)
if(Vnum==G.Vexnum&&Eum==2*(G.vexnum-1))
return true;//符合树的条件
else
return false;//不符合树的条件
}
void DFS(Graph&G,int v,int &Vunm,int& Enum,int visited[]){//深度优先遍历图G,并且附加功能为统计访问过的顶点数和边数,通过Vnum和Enum来记录返回
visited[v]=TRUE; Vnum++;//作访问标记,顶点计数
int w=FirstNeighbor(G,v);//取v的第一个邻接顶点
while(w!=-1){//深度遍历,因此只要邻接顶点还有下一个邻接顶点存在,就新的邻接点开始继续遍历
Enum++;//边存在,边计数
if(!visited[w])//当该新邻接顶点之前未访问过才可以进行新一轮的DFS,(访问,并且进行计数)
DFS(G,w,Vnum,Enum,visited);//对其调用DFS遍历
w=NextNeighbor(G,v,w);
}
}