栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

克鲁斯卡尔算法建立最小生成树

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

克鲁斯卡尔算法建立最小生成树

克鲁斯卡尔算法,是每次选出权值最小的边构成最小生成树,选出边时,要避免形成环。最终选出结点数减一条边即可。(避免形成环的问题,采用标号法(并查集),一开始,每个结各自为一个集合,分别给出各自不同大小的标号,选出的边的两端结点的标号将大的那个改成小的,以后选出的边的端点标号不能相同。)

#include
#define N 100
int sum=0;//权值和 
using namespace std;
//边节点 
typedef struct vexnode {
	int adjvex;
	char v;
	struct  vexnode *nextarc;
	float info;
}ArNode;
typedef struct Vnode{  //顶点信息 
	char data;
	ArNode *firstarc; //指向第一个边结点 
}Vonde,Adjust[100]; 
typedef struct {
	Adjust survice;//邻接表 
	int vexnum,acrnum;//图的当前顶点数和边数 
}ALgraph;

//邻接表查找
 int locate1(ALgraph&R, char v,int n){//找出字符为v的下标 
 	int j,i;
 	for(i=1;i<=n;i++){
 		if(R.survice[i].data==v){
 			j=i;
		 }
	 }
	 return j;
 } 
void creatUND(ALgraph &R){
	char v1,v2;//顶点的数据值 
	int i1,i2;//输入的两个顶点的位置和权值 
	float i3;//权值 
	printf("请输入顶点数和边数:"); 
	cin>>R.vexnum>>R.acrnum; //输入顶点数和边数 
	printf("请输入各个顶点的值:n"); 
	for(int i=1;i<=R.vexnum;i++){
		cin>>R.survice[i].data;//输入各个顶点的信息 
		R.survice[i].firstarc=NULL;
		 
	}
   
    printf("请输入每条边依附的两个结点和权值:n");
	for(int i=1;i<=R.acrnum;i++){
		cin>>v1>>v2>>i3;
		i1=locate1(R,v1,R.vexnum);
		i2=locate1(R,v2,R.vexnum);
		ArNode *p=new ArNode;
		p->info=i3; //记录权值 
		p->v=v1;//记录边点的值 
		p->adjvex=i2;// 记录顶点的值 
		p->nextarc=R.survice[i2].firstarc; //利用头插法把第i1个的顶点插入到第i2个邻接表中 
		R.survice[i2].firstarc=p;//建立的邻接表表示的图为有向图,所以只记录一边,所以下面的部分代码给注释掉了 
	
	} 
	     
}
//协助结构体,用来记录边的起始点,终点,权值信息 
typedef struct end{
	 char start;//边的起点 
	 char end;//变得终点 
	 int  w;//边的权值 
}Edge[100]; 
  
//将边按照权值大小进行排序 
void sort(Edge &E,ALgraph &R){
	char b;
	int num;
	 int m=R.acrnum;
	 for(int i=0;ij){
	  	return i;
	}else 
	return j;
} 
//找出两结点的标号的小的那个
int min (int i,int j){
	if(iv;
	   		E[u].w=p1->info;
	   		u++;
	   		p1=p1->nextarc;
		   }
	   }
	   sort(E,G); //将每条边按照权值的大小排序
	   int n=0;//要挑选出边的下标 
	   for(int i=0;i<=G.vexnum-1;i++){//边的结构体下标是从零开始的 
	   	char head1 =E[n].start;//记录选出边的起始点 
	   	char end1 =E[n].end;//记录选出边的终点 
	   	if(parent[locate1(G,head1,G.vexnum)]!=parent[locate1(G,end1,G.vexnum)]){// 如果结点的标号不相等的话,将权值加上 
	   		  sum+=E[n].w; 
		  int  maxv=max(parent[locate1(G,head1,G.vexnum)],parent[locate1(G,end1,G.vexnum)]);//得到边两端结点标号的最大值 
		  int  minv=min(parent[locate1(G,head1,G.vexnum)],parent[locate1(G,end1,G.vexnum)]);//得到边两端结点标号的最小值 
		     parent[locate1(G,head1,G.vexnum)]=minv;  
			 parent[locate1(G,end1,G.vexnum)]=minv;//他俩选出后成为一个集合,将标号都改为最小值 
		
			 for (int j=1;j<=G.vexnum;j++){//将结点中所有标号都为边两端标号最大值的结点标号都改为最小值 
			 	if(parent[j]==maxv){
			 		  parent[j]=minv;
				 }
			 }
			
		 printf("<%c ,%c> n",head1,end1); //输出找出变的两个结点 
		
	}
		 n++;
	   } 
	   printf("最小权值之和为:%d",sum); 
	   
	
}
int main (){
	ALgraph R;
	Edge E;//有关边的结构体 
	creatUND(R);
	minspantree_Kruskal(R,E);
	return 0;
} 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/648175.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号