Kruskal算法的实现

利用Krusal算法求一个图的最小生成树,设计Kruskal算法求解邻接矩阵存储结构最小生成树的函数。
首先Kruskal算法是以为目的构建的,要构建最小生成树,我们可以分成以下几步。
1.将邻接矩阵先化为顶点,顶点,权值的数组。
2.将权值的大小按从小到大的顺序排列。
3.依次将权值从小到大的边放入个顶点之间。
4.如果放入权值的边形成了环就将其抛出。
5.当放入边数等于顶点数减一时,成功。

实现函数
Kruskal.h

#include "SeqList.h"
#include "AdjMGraph.h"
#include "AdjMGraphCreate.h"

void Swapn(RowColWeight* a, int i, int j)
{
	int temp;
	temp = a[i].row;
	a[i].row = a[j].row;
	a[j].row = temp;
	temp = a[i].col;
	a[i].col = a[j].col;
	a[j].col = temp;
	temp = a[i].weight;
	a[i].weight = a[j].weight;
	a[j].weight = temp;
}
void MinSpanTree_Kruskal(AdjMWGraph G, RowColWeight a[])
{

	int i, j = 0, temp, k = 0, n, m, num = 0;


	int parent[MaxSize];  //用来判断边与边是否会成环



	for (i = 0; i < G.Vertices.size - 1; i++)
	{
		for (j = i + 1; j < G.Vertices.size; j++)
		{
			if (G.edge[i][j] < MaxWeight)
			{
				a[k].row = i;
				a[k].col = j;
				a[k].weight = G.edge[i][j];
				k++;
			}
		}
	}



	for (i = 0; i < G.numOfEdges; i++)
	{
		for (j = i + 1; j < G.numOfEdges; j++)
		{
			if (a[i].weight > a[j].weight)
			{
				Swapn(a, i, j);
			}
		}
	}
	printf("权值排序之后的为:\n");
	for (i = 0; i < G.numOfEdges; i++)
	{
		printf("(%c, %c)= %d\n", a[i].row + 97, a[i].col + 97, a[i].weight);
	}




	for (i = 0; i < G.Vertices.size; i++)
	{
		parent[i] = 0;  //初始化数组值为 0
	}

	//循环每一条边
	for (i = 0; i < G.numOfEdges; i++)
	{
		n = Find(parent, a[i].row);
		m = Find(parent, a[i].col);
		if (n != m)  //n!=m,说明没有成环,加入生成树
		{
			//将此边的结尾顶点放入下标为起点的parent中(n是起始顶点,m是结尾顶点)
			//n---m 这条边符合条件
			//表示该顶点已经在生成树集合中
			parent[n] = m;
			printf("Kruskal最小生成树步骤为:\n");

			printf("第%d步(%c,%c),weight = %d\n", ++num, a[i].row + 97, a[i].col + 97, a[i].weight);
		}
	}
}

//查找连线顶点的尾部下标
int Find(int* parent, int f)
{
	while (parent[f] > 0)
	{
		f = parent[f];
	}
	return f;
}

测试主函数

#include <stdio.h>
#include <stdlib.h>
typedef char DataType;
#define MaxSize 10
#define MaxVertices 10
#define MaxWeight 999
#include "SeqList.h"
#include "Kruskal.h"
#include "AdjMGraph.h"
#include "AdjMGraphCreate.h"
int main(void)
{
	AdjMWGraph g1;
	DataType a[] = { 'a','b','c','d','e' };
	RowColWeight rcw[] = { {0,1,3},{0,4,1},
		{1,2,5},{1,4,4},{2,4,6},{2,3,2},
		{3,4,7 } };
	int n = 5, e = 7;
	int i, j,z;
	CreatGraph(&g1, a, n, rcw, e);
	printf("顶点的集合为:");
	for (i = 0; i < g1.Vertices.size; i++)
		printf("%c ", g1.Vertices.list[i]);
	printf("\n");
	for (i = 0; i < g1.Vertices.size; i++)
	{
		for (j = 0; j < g1.Vertices.size; j++)
		{
			g1.edge[j][i] = g1.edge[i][j];//实现无向图邻接矩阵的对称性
		}
	}
	printf("权值集合为:\n");
	for (i = 0; i < g1.Vertices.size; i++)
	{
		for (j = 0; j < g1.Vertices.size; j++)
			printf("%5d", g1.edge[i][j]); 
		printf("\n");
	}
	MinSpanTree_Kruskal(g1,rcw);
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值