8.数据结构与算法--树-(带全最小生成树-克鲁斯卡尔算法)

带全最小生成树-克鲁斯卡尔算法

 边的名称按照权值来排序

 

  ---变成了---> 

 

------> 

 

算法代码:

struct Edges
{
	int begin;
	int end;
};

int Find(int* parent, int f)
{
	while (parent[f] > 0)
	{
		f = parent[f];
	}
	return f;
}
//Kruskal 算法生成最小生成树
void MiniSpanTree_Kurskal(MGraph G)
{
	int n, m;
	Edges edges[MAGEDGE]; //定义边集数组
	int parent[MAXVET];//定义parent数组,用来判断边与边是否形成环路

	for (int i = 0; i < G.numVertexes; i++) 
	{
		parent[i] = 0;
	}

	for (int i = 0; i < G.numEdges; i++)  //以边的个数,作为循环次数
	{
		n = Find(parent, edges[i].begin);//n=4  2  1  5  3  8  6  6 6
		m = Find(parent, edges[i].end);  //m=7  8  5  8  7  6  6  6 7

		if (n != m) //如果n==m,则形成环路,不满足
		{
			parent[n] = m; //将此边的结尾顶点放入下标为起点的parent数组中,表示此顶点已经在生成树集合中
			printf("(%d, %d) %d", edges[i].begin, edges[i].end, edges[i].weight);
		}
	}
}

思维过程:

比如有这样的表,begin表示起点位置,end表示终点位置,weigth表示权重,按照权重的大小对edges数组排序

初始化parent数组:

1.进入i=0的for循环, edges[0].begin=4时,进入Find函数,返回f=4 ,所以n=4;  edges[0].end=7时,进入Find函数,返回f=7,所以m=7;不构成环路,则parent[4]=7;

因此parent数组改变为:

此时,V4——V7便已经指过了。

2.进入i=1的for循环, edges[0].begin=2时,进入Find函数,返回f=2 ,所以n=2;  edges[0].end=8时,进入Find函数,返回f=8,所以m=8;不构成环路,则parent[2]=8;

此时parent数组为:

此时,V2——V8便已经连接了

3 以此类推.....  ....V0——V1便已经连接了 

4.以此类推......V0——V5便已经连接了

5以此类推........V1——V8便已经连接了

6.以此类推... ....V3——V7便已经连接了

7.以此类推... ....V1——V6便已经连接了  ,

此时连接图为: 

8.进入for循环,edges[0].begin=5时,进入Find函数,返回f=6 ,所以n=6;  edges[0].end=6时,进入Find函数,返回f=6,所以m=6;n==m 构成环路,则舍弃V5——V6的连接;

9.进入for循环,edges[0].begin=1时,进入Find函数,返回f=6 ,所以n=6;  edges[0].end=2时,进入Find函数,返回f=6,所以m=6;n==m 构成环路,则舍弃V1——V2的连接;

10.进入for循环,edges[0].begin=6时,进入Find函数,返回f=6 ,所以n=6;  edges[0].end=7时,进入Find函数,返回f=7,所以m=7;

此时parent数组为:

不构成环路,V6——V7便已经连接了.

此时连接图为:,最小生成树已经构建完成!

11.V3——V4舍弃,V3——V8舍弃,V2——V3舍弃,V3——V6舍弃,V4——V5舍弃,

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值