图的最小生成树——克鲁斯卡尔算法

接下来介绍克鲁斯卡尔算法

克鲁斯卡尔算法的核心是以边为核心,不断实现“加边”的过程,和普里姆算法只是不同的两种方法,实现的结果本质是一样的。

另一种最小生成树算法普里姆算法

头文件,数据结构,定义
#include<iostream>
#define Maxvexnum 10
#define MaxInt 10000
using namespace std;
typedef char vertextype;
typedef int arctype;
int vexset[Maxvexnum];
typedef struct {
	vertextype vexs[Maxvexnum];
	arctype arcs[Maxvexnum][Maxvexnum];
	int vexnum, arcnum;
	struct edge;
}AM_Graph;
struct{
	vertextype Head;
	vertextype Hail;
	arctype lowcost;
}edge[Maxvexnum];
vexset[]数组表示的是连通分量,初始化为每一个顶点即为一个连通分量,edge[]表示的是每条边的两个顶点和权值。
首先我们需要对这个edge[]数组进行排序,原因在于:我们需要优先选出权值最小的边(如果构成了回路,才会选择第二小的边)
排序使用的是冒泡排序算法,需要注意的是交换的是一条边,不光只交换权值,还有首尾两个顶点。
void sort_AM(AM_Graph& g)//冒泡排序,从小到大的顺序,把最大的数放在最后一个
{
	int length = g.arcnum;
	while (length > 0)
	{
		for (int i = 0; i < length-1; i++)
			if (edge[i].lowcost > edge[i + 1].lowcost)
			{
				//交换数值
				int exchange_lowcost = edge[i].lowcost;
				edge[i].lowcost = edge[i + 1].lowcost;
				edge[i + 1].lowcost = exchange_lowcost;
				//交换head
				char exchange_head = edge[i].Head;
				edge[i].Head = edge[i + 1].Head;
				edge[i + 1].Head = exchange_head;
				//交换hail
				char exchange_hail = edge[i].Hail;
				edge[i].Hail = edge[i + 1].Hail;
				edge[i + 1].Hail = exchange_hail;
			}
		length--;
	}
	for (int i = 0; i < g.arcnum; i++)
		cout << edge[i].Head << edge[i].Hail << edge[i].lowcost << endl;
}

克鲁斯卡尔算法的c++实现

void minispantree_Kruskal(AM_Graph& g)
{
	sort_AM(g);
	for (int i = 0; i < g.vexnum; i++)
		vexset[i] = i;
	for (int i = 0; i < g.arcnum; i++)
	{
		int v1 = LocateVex_AM(g, edge[i].Head);
		int v2 = LocateVex_AM(g, edge[i].Hail);
		int vs1 = vexset[v1];
		int vs2 = vexset[v2];
		if (vs1 != vs2)
		{
			cout << edge[i].Head << "-" << edge[i].Hail << endl;
			for (int j = 0; j < g.vexnum; j++)
				if (vexset[j] == vs2)
					vexset[j] = vs1;
		}
	}
}
需要值得注意的是,如果一条边的两个点在同一连通分量上,意味着构成了回路,那么这条边就不能要,是多余的。如果不在一个连通分量上,输出这条边后,需要把这条边也放在之前的连通分量里面。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值