c++实现kruskal算法(最小生成树)

这篇博客介绍了如何实现Kruskal算法来构造一个图的最小生成树。首先,定义了Edge结构体表示边,以及Graph类用于存储图的顶点和边。然后,通过输入顶点和边,利用冒泡排序对边按权值进行排序。在Kruskal算法中,通过查找根节点避免形成环路,并逐步构建最小生成树。最后,博客展示了在主函数中如何调用这些方法并输出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
using namespace std;

const int MAX = 15;  //数组最大容量

struct Edge
{
	int begin;
	int end;
	int weight;
};


class Graph
{
private:
	int vertex_num; //顶点数
	int edge_num; //边数
	Edge edges[MAX]; //边集数组
	char vertex[MAX]; //顶点数组
	int parent[MAX]; //定义一组数组用来判断边与边是否形成回路
	int locate(char ch); //定位
	void sort(Edge *edges); //排序
	int find_root(int *parent, int node); //查找根结点

public:
	Graph(int v, int e); //创建邻接矩阵
	void kruskal(); //kruskal算法
	
};

//定位
int Graph::locate(char ch)
{
	int i = 0;
	for (; i < this->vertex_num; i++)
	{
		if (this->vertex[i] == ch)
		{
			break;
		}
	}
	return i;
}

//构造函数
Graph::Graph(int v, int e) : vertex_num(v), edge_num(e)
{
	//输入图中顶点
	cout << "请输入这" << this->vertex_num << "个顶点:" << endl;
	for (int i = 0; i < this->vertex_num; i++)
	{
		cin >> this->vertex[i];
	}

	//初始化parent数组
	for (int i = 0; i < this->vertex_num; i++)
	{
		this->parent[i] = -1; //顶点初始化全部为根结点,-1表示没有双亲结点
	}

	//构造边集数组
	cout << "请输入两个顶点及其权值:" << endl;
	for (int i = 0; i < this->edge_num; i++)
	{
		char first, second;
		cin >> first >> second >> edges[i].weight;
		edges[i].begin = this->locate(first);
		edges[i].end = this->locate(second);
	}
}


//冒泡排序(将边集数组按权值从小到大排序)
void Graph::sort(Edge *edge)
{
	for (int i = 0; i < this->edge_num - 1; i++)
	{
		for (int j = 0; j < this->edge_num - i - 1; j++)
		{
			if (edges[j].weight > edges[j + 1].weight)
			{
				//交换权值
				int temp1, temp2, temp3;
				temp1 = edges[j + 1].weight;
				edges[j + 1].weight = edges[j].weight;
				edges[j].weight = temp1;

				//交换begin
				temp2 = edges[j + 1].begin;
				edges[j + 1].begin = edges[j].begin;
				edges[j].begin = temp2;

				//交换end
				temp3 = edges[j + 1].end;
				edges[j + 1].end = edges[j].end;
				edges[j].end = temp3;
			}
		}
	}
}


//查找根
int Graph::find_root(int *parent, int node)
{
	while (this->parent[node] > -1)
	{
		node = this->parent[node];
	}
	return node;
}


//kruskal算法
void Graph::kruskal()
{
	int i, m, n;

	//为边集数组按照权值从小到大排序
	this->sort(this->edges);

	//循环每一条边
	for (i = 0; i < this->edge_num; i++)
	{
		//找到根结点
		n = this->find_root(this->parent, this->edges[i].begin);
		m = this->find_root(this->parent, this->edges[i].end);
		//如果n不等于m,说明此边没有与现有的生成树形成环路
		if (n != m)
		{
			//将此边的纳入生成树
			this->parent[n] = m;
			//打印最小生成树的两个顶点及其权值
			cout << "("
				<< this->vertex[this->edges[i].begin]
				<< ","
				<< this->vertex[this->edges[i].end]
				<< ")\t权值为:"
				<< this->edges[i].weight << endl;
		}
	}
}



int main()
{
	int v = 0, e = 0;
	cout << "请输入图的顶点数和边数:" << endl;
	cin >> v >> e;
	Graph g(v, e);
	cout << "最小生成树:" << endl;
	g.kruskal();


	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值