Kruskal算法的实现

 Kruskal算法是一种按权值的递增次序选择合适的边来构造最小生成树的方法。通常Kruskal算法用于求解稀疏图的最小生成树

  • Kruskal算法的过程:
    (1)置U的初值等于V(即包含图G中的全部顶点),置TE(最小生成树的边集)的初值为空集
    (2)将图G中的边按权值从小到大的顺序依次选取:
              ① 若选取的边未使生成树T形成回路,则加入TE中
              ②否则舍弃,直到TE中包含(n-1)条边为止
  • 具体过程如下图所示:
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
  • Kruakal算法的设计:
    (1)图采用哪种存储结构更合适?答:邻接矩阵
    (2)边的排序问题怎么解决?答:设计一种排序方法,这里采用冒泡排序法
    (3)如何解决加入一条边后是否出现回路?答:采用连通分量编号或顶点集合编号
  • Kruakal算法代码实现:
#include <iostream>
#include<math.h>
#define MAXV 100

typedef struct
{
	int n;	//顶点信息
}VertexType;

typedef struct
{
	int edges[MAXV][MAXV];	//邻接矩阵
	int n, e;	//顶点数、边数
	VertexType vexs[MAXV];	//存放顶点信息
}MGraph;

typedef struct
{
	int u;	//边的起点
	int v;	//边的终点
	int w;	//边的权值
}Edge;

void InsertSort(Edge E[], int n)
{
	int i, j;
	Edge tmp;
	for (i = 0; i < n - 1; i++)
	{
		for(j=n-1;j>i;j--)
			if (E[j].w < E[j - 1].w)
			{
				tmp = E[j];
				E[j] = E[j - 1];
				E[j - 1] = tmp;
			}
	}
}

void Kruskal(MGraph g)
{
	int i, j;
	int u1=0, v1=0;	//一条边的头尾顶点
	int sn1=0, sn2=0;	//边对应辅助数组的位置
	int vset[MAXV];	//用于判断加入一条边后会不会出现回路
	Edge E[MAXV];	//存放所有的边
	int k=0;	//E中的边的数目
	for(int i=0;i<g.n;i++)
		for(int j=i;j<g.n;j++)
			if (g.edges[i][j] != 0)
			{
				E[k].u = i;
				E[k].v = j;
				E[k].w = g.edges[i][j];
				k++;
			}		//将图中所有的边的信息都保存到E结构体
	InsertSort(E, g.e);

	for (i = 0; i < g.n; i++)
		vset[i] = i;
	k = 1;	//开始构建最小生成树的第一条边
	j = 0;	//E中的下标
	while (k < g.n)
	{
		u1 = E[j].u;
		v1 = E[j].v;
		sn1 = vset[u1];
		sn2 = vset[v1];
		if (sn1 != sn2)
		{
			printf("(%d,%d),%d\n", u1, v1, E[j].w);
			k++;
			for (i = 0;i < g.n; i++)
			{
				if (vset[i] == sn2)
					vset[i] = sn1;
			}
		}
		j++;

	}
}

int main()
{
	MGraph G;
	for (int i=0; i < 7; i++)
		for (int j = 0; j < 7; j++)
			G.edges[i][j] = 0;
	G.edges[0][1] = G.edges[1][0] = 28;
	G.edges[0][5] = G.edges[5][0] = 10;

	G.edges[1][2] = G.edges[2][1] = 16;
	G.edges[1][6] = G.edges[6][1] = 14;

	G.edges[2][3] = G.edges[3][2] = 12;

	G.edges[3][4] = G.edges[4][3] = 22;
	G.edges[3][6] = G.edges[6][3] = 18;

	G.edges[4][5] = G.edges[5][4] = 25;
	G.edges[4][6] = G.edges[6][4] = 24;
	G.n = 7;
	G.e = 9;
	/*for (int i = 0; i < 7; i++)
	{
		for (int j = 0; j < 7; j++)
			printf("%d ", G.edges[i][j]);
		printf("\n");
	}*/


	Kruskal(G);

}
  • 输出结果:
    在这里插入图片描述
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值