【数据结构与算法基础】最小生成树算法原理及实现

本文介绍了最小生成树的概念及其在无向有权连通图上的应用。重点讲解了Kruskal和Prim两种算法,包括它们的原理、实现及复杂度分析。Kruskal算法依赖于并查集,而Prim算法则类似于Dijkstra,从单个节点扩展。此外,还提到了暴力和堆优化的策略。最后,列举了系列文章的其他主题。
摘要由CSDN通过智能技术生成

前言

数据结构,一门数据处理的艺术,精巧的结构在一个又一个算法下发挥着他们无与伦比的高效和精密之美,在为信息技术打下坚实地基的同时,也令无数开发者和探索者为之着迷。

也因如此,它作为博主大二上学期最重要的必修课出现了。由于大家对于上学期C++系列博文的支持,我打算将这门课的笔记也写作系列博文,既用于整理、消化,也用于同各位交流、展示数据结构的美。

此系列文章,将会分成两条主线,一条“数据结构基础”,一条“数据结构拓展”。“数据结构基础”主要以记录课上内容为主,“拓展”则是以课上内容为基础的更加高深的数据结构或相关应用知识。

欢迎关注博主,一起交流、学习、进步,往期的文章将会放在文末。


最小生成树,总是和最短路径一起出现在入门图论的大道上。是一个有趣且重要的问题,有些地方又叫它做最小支撑树。

讨论最小生成树的前提是在无向有权连通图上。在非连通的无向图上,只能找到最小生成森林。在无权图上,可以寻找生成树,但是生成树无大小之分。

我们定义,在无向连通图上的最小生成树为边权和最小的生成树。

下面,来介绍两种经典的生成最小生成树的算法:

kruskal算法

kruskal算法利用贪心的思想。将所有的边按照边权升序排序,依次尝试加入图。加入时如果该边的两顶点已经连通,则不将其加入,否则可以加入。

显然,每次加入可使图中的森林数量减一,最终加入n-1条边。

用来维护顶点连通的方式是使用并查集结构,往期内容有整理过并查集相关知识(点这里)。

排序算法则见仁见智,可以使用各种方式进行排序,在使用较优复杂度的排序算法( O ( m l o g 2 m ) O(mlog_2m) O(mlog2m))及较优复杂度的并查集实现( O ( m l o g 2 m ) O(mlog_2m) O(mlog2m))情况下,该算法复杂度为 O ( m l o g 2 m ) O(mlog_2m) O(mlog2m)

下面的示例就是使用kruskal算法完成最小生成树并计算最小权值和的过程:

原图如下:
在这里插入图片描述

生成过程如下:
在这里插入图片描述
算法实现如下:

#include<iostream>
#include<algorithm>
using namespace std;

struct Edge{
   
	int v1;
	int v2;
	int val;
};
Edge edges[M];//边集
int fa[N];//并查集使用父亲数组
int n,m;

int find(int k){
   //查询集合代表元
	if(fa[k] == k){
   
		return k;
	}
	fa[k] = find(fa[k]);
	return fa[k];
}

bool cmp(const Edge & x,const Edge & y){
   //边结点比较函数,用于排序
	return x.val < y.val;
}

int kruskal(){
   
	sort(edges,edges + m,cmp);//边集排序,这里使用stl中的快排

	int ans = 0;
	Edge edge;
	for(int i = 0;i < m;i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值