设计一个算法,判断一个无向图G是否为一棵树。若是一棵树,则返回true,否则返回false。
思想:无向图是树有两个判断方法:①n个顶点n-1条边的连通图。②无回路的连通图。本题选用第一种方法。利用深度优先遍历,记录访问的顶点数和边数,如果一次DFS访问到n个顶点,n-1条边,则该无向图是树。
代码:
typedef char GElemType;
typedef struct ArcNode{
int adjvex; //该边所指向的顶点的位置
struct ArcNode *next;//指向下一条边的指针
}ArcNode;
//顶点的结点结构
typedef struct VNode{
GElemType data;//顶点信息、
ArcNode *first;//指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];//AdjList表示邻接表类型
//图的结构定义
typedef struct{
VNode *vertices; //定义一个数组vertices,是vertex的复数形式
int vexNum,arcNum; //图的当前顶点数和弧数
}ALGraph;
//深度优先遍历 ,图的邻接表表示法
void DFS(ALGraph* G,int v,int &Vnum,int &Enum,bool *vistied){
visited[v]=true;Vnum++; //标记访问顶点,和统计顶点个数
ArcNode *arc=G->vertices[v].first;//取第一条边
while(arc!=NULL){
Enum++;
if(visited[arc->adjvex]==false){
DFS(G,arc->adjvex,Vnum,Enum,visited);//递归访问
}
arc=arc->next;
}
}
//图的邻接表表示法
bool isTree(ALGraph *G){
bool *visited=(bool*)malloc(sizeof(bool)*G->vexNum);//初始化visited数组
for(int i=0;i<G->vexNum;i++) visited[i]=false;
int Vnum=0,Enum=0;//DFS记录的边和顶点的个数
DFS(G,O,Vnum,Enum,visited);
//是否为树。无向图每条边被访问两次。
return Vnum=G->vexNum&&Enum=2*(G->vexNum-1);
}