学懂最小生成树(克鲁斯卡尔算法)

本节,小编将带大家了解最小生成树的第二种构成算法——克鲁斯卡尔算法(Kruskal algorithm) 

当然,对另一种算法感兴趣的朋友可以看看之前的这篇文章:学懂最小生成树(普里姆算法)

目录

一.实现原理

 二.代码实现


一.实现原理

克鲁斯卡尔算法的思想是:

将所有边从小到大排序,然后依照边从小到大将顶点链式连接起来,直到所有的顶点连成一条链。

原理图:

CSDN@就要宅在家

 二.代码实现

实现克鲁斯卡尔算法,我们需要准备两个“工具”,一是结构体数组,里头存放边和该边的两个顶点,用途是升序存放边;二是下标数组,用途是存放到到每个顶点的最小边的顶点下标。

以上图为例:

下标数组设为int vexlist[4];

最终里头存放的下标分别

vexlist[0]vexlist[1]vexlist[2]vexlist[3]
0301

以vexlis[1]为例,意思就是到顶点b的最小边是d指向的。

上代码!

void MiniTree_kruskal(UND* u)//排序邻接矩阵所有边权值,从小到大放入克鲁斯卡尔数组
{
	MiniTree_K tm;
	int vexlist[MAXVEX];//建立顶点数组,用于标识个个顶点分量
	sort_K(*u, tm);//升序排序边
	for (int i = 0; i < u->vexnum; i++)//初始化下标数组
	{
		vexlist[i] = i;
	}
	for (int i = 0; i < u->arcnum; i++)//主循环
	{
		int v1 = Findvex(u, tm[i].head);//找这个边的头下标
		int v2 = Findvex(u, tm[i].tail);//找尾下标
		if (vexlist[v1] != vexlist[v2])
		{
			cout << tm[i].head << "->" << tm[i].tail << endl;//打印
			int k = vexlist[v2];//如果有的顶点已经与尾连接起来,将它的vexlist指向头,防止出现路径循环
			for (int j = 0; j < u->vexnum; j++)//找顶点是否与尾连起来
			{
				if (vexlist[j] == k)//如果与尾连起来,那该顶点与尾一起指向头
					vexlist[j] = vexlist[v1];
			}
		}
	}

}
void sort_K(UND u, MiniTree *tm)//排序
{
	int sub = 0;//
	for (int n = 0; n < u.arcnum; n++)//
	{
		int x = 0, y = 0, mininum = Maxnum;
		for (int i = 0; i < u.vexnum; i++)//
		{
			for (int j = 0; j < u.vexnum; j++)
			{
				if (u.form[i][j] < mininum)
				{
					x = i; 
					y = j;
					mininum = u.form[i][j];
				}
			}
		}
		tm[sub].head = u.list[x];
		tm[sub].tail = u.list[y];
		tm[sub].weight = u.form[x][y];
		u.form[x][y] = Maxnum;
		sub++;
	}
}

😗创作不易,恳请三连支持,如有错误,敬请斧正

评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

就要 宅在家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值