判断图是否为树(C语言实现)

核心思想:
图是树需要满足两个条件:
(1)图中结点均连通,即结点属于同一个集合;
(2)结点满足只有一个结点入度为0,其余结点入度为1;

算法步骤:
(1)一次读入一条边,将读入的边对相应的两个结点分别初始化,若该点之前不存在,则创建一个包含该点的新集合;同时,对于后面的结点,入度要进行加1;
(2)比较该边的两个端点是否在同一个集合,若不在则将该边的两个端点所在的两个集合进行合并;
(3)重复步骤(1)、(2),直到输入结束;
(4)根据图是树的条件去进行判断,满足则是树,否则不是树。

实例以及代码

//定义图结点的数据结构
typedef struct{
	int number; //结点的编号
	int home;   //结点属于的集合编号
	int ru;     //结点的入度
}Dian;

int k=0;   //结点个数
//对于输入的每个结点,进行相应的初始化
//返回的是该结点在结构体数组g[]中的下标
int AddDot(Dian g[],int a,int t){
	int i;
	for(i=0;i<k;i++)
		if(a==g[i].number)
		{                  
			if(t==1)     //这里有个易错点,就是当点
				g[i].ru++;//存在时,会选择直接退出   
			return i;
		}
	g[k].number=a;
	g[k].home=a;
	g[k++].ru=0;
	if(t==1)
        g[k-1].ru++;
	return k-1;
}
//判断边两个端点是否属于一个集合,若不,则将两个集合合并
void Merge(Dian g[],int loc1,int loc2){
	int t,i;
	t=g[loc1].home;
	for(i=0;i<k;i++)
		if(g[i].home==t)
			g[i].home=g[loc2].home;
}
//读入数据的模块
void Input(Dian g[]){
	int a,b,loc1,loc2;
	printf("请输入边(以0 0作为结束):\n");
	scanf("%d %d",&a,&b);
	while(a!=0)
	{
		loc1=AddDot(g,a,0);
		loc2=AddDot(g,b,1);
		Merge(g,loc1,loc2);
		scanf("%d %d",&a,&b);
	}
}
//根据已有数据进行判断
bool Judge(Dian g[]){
	int i,t,mark=0;
	t=g[0].home;
	for(i=0;i<k;i++)
	{
		if(g[i].home!=t) //若结点不属于同一集合,则F
			return false;
		if(g[i].ru>1) //如某一个结点的入度大于1,则F
			return false;
		if(g[i].ru==0)  //记录结点入度为0的结点数
			mark++;
	}
	if(mark!=1)    //若个数不为1,则返回F
		return false;
	return true;  //否则,返回T
}
//格式化输出
void Output(bool t){
	if(t)
		printf("可以构成一棵树。");
	else
		printf("无法构成一棵树");
} 
//主函数,负责上述函数的调用
int main(){
	Dian g[20];
	bool Tree;
	Input(g);
	Tree=Judge(g);
    Output(Tree);
	return 0;
}

运行结果:
在这里插入图片描述

原创文章 16 获赞 5 访问量 1002

猜你喜欢

转载自blog.csdn.net/qq_42453280/article/details/106001219