数据结构-克鲁斯卡尔算法,普利姆算法(求最小生成树)

news2024/11/23 15:20:59

当然了昨天晚上写了求两源点之间最少权值和,就不得不再写一下另外两个求最小生成树的算法分别是克鲁斯卡尔和普利姆了,话不多说直接进入主题

目录

并查集:

克鲁斯卡尔算法(与并查集结合起来):

普利姆算法:


并查集:

为啥先说并查集,因为对我们下面看克鲁斯卡尔有用,先引入并查集的例子进行初步讲解

首先什么是并查集:其实通俗来讲就是将一系列有特定关系的事务给他总合起来

举一个简单例子Eg:比如a跟b有关系,b是a的父亲,然后a和c是兄妹关系,那么b也就是c的父亲 

所以就是按图表示为

第一种:a->b,a-c(平级)=>c->b

第二种:a->b,b->c=>a->b->c

第三种:a->b->e,c->e=>(a,c,b)->e

这就是大体理解一下,为了做到上面的效果我们需要两个数组来存储,第一个用来存储每一个节点的祖先分别是什么,第二个用来存储当前节点的祖先下面有几个子节点

先看初始化:

void Init(int n)
{
	for(int i=1; i<=n; i++)
	{
		arr[i]=i;          //arr是当前节点的祖先节点,所以刚开始每个人的祖先节点都是自己本身
		rank[i]=1;         //当前下面的子节点只有本身节点所以就为1
	}
}

然后就是寻找祖先节点:

int find(int x)
{
	if(x==arr[x])          //如果是当前节点的祖先就是自己那就直接返回
	{
		return x;
	}
	else
	{
		return arr[x]=find(arr[x]); //如果是其他节点,就继续去寻找其他节点直到找到最终的祖先节点
	}
}

然后将节点进行结合:

void unite(int x,int y)
{
	x=find(x);               //首先找两个节点的祖先节点
	y=find(y);
	if(x==y)                 //如果祖先是同一个节点那就不需要结合
	{ 
		return;
	}
	if(rank[x]<rank[y])     //不一样看当前的级别,谁的级别高谁就是他们两个的总结点
	{
		arr[x]=y;
	}
	else
	{
		arr[y]=x;
		if(rank[x]==rank[y])
		{
			rank[y]++;        //如果相同级别看你当前是将谁赋予了祖先节点,如果是x为祖先节点,则y++,反之亦然
		}
	}
}

 

克鲁斯卡尔算法(与并查集结合起来):

众所周知啊克鲁斯卡尔(Kruskal)算法就是用边权值进行寻找最小生成树,先将边的最小值进行一个排序然后从最小值开始寻找生成一颗完整的树

但是存在一个问题就是说什么情况下可以称作为一颗完整的树呢?

答案很简单我们用并查集来解决找祖先的问题。

所以我们先将整个已知条件进行按权值排序,这里用啥都行,希尔,快排,归并,冒泡都可以

我用的冒泡(简单一点):

void sort(int m)
{
	Node N;
	for(int i=1; i<=m; i++)
	{
		for(int j=i; j<=m; j++)
		{
			if(a[i].e>a[j].e)
			{
				N=a[i];
				a[i]=a[j];
				a[j]=N;
			}
		}
	}
}

然后就是实现克鲁斯卡尔算法了:

int kruskal(int n,int m)
{
	int result=0,n_edge=0,f1,f2,j=1;
	for(int i=1; i<=m; i++)
	{
		f1=find(arr[a[i].edga_first]);          //先找两人的共同祖先
		f2=find(arr[a[i].edga_second]);
		if(f1!=f2)                              //一样的话就不用算了
		{
			unite(f1,f2);                   //不一样直接合并因为我们已经按最小权值进行了排序
			result+=a[i].e;               //将当前的总权值进行跟新
			n_edge++;                    //表明当前的树有几个节点
		}
		if(n_edge==n-1)                 //如果节点数已经够了总结点就可以退出了
		{
			return result;
		}
	}
	return -1;                        //如果无法生成最小数就返回-1
}

看看整体实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define max 200005
typedef struct graph                 //定义一个结构体保存边边权三个值 
{
	int edga_first,edga_second;
	int e;
} Node;
int arr[max],rank[max];                 //arr为祖先节点的定义,rank为当前祖先节点的子节点数 
Node a[max];
void sort(int m)
{
	Node N;
	for(int i=1; i<=m; i++)
	{
		for(int j=i; j<=m; j++)
		{
			if(a[i].e>a[j].e)
			{
				N=a[i];
				a[i]=a[j];
				a[j]=N;
			}
		}
	}
}
void Init(int n)
{
	for(int i=1; i<=n; i++)
	{
		arr[i]=i;
		rank[i]=1;
	}
}
int find(int x)
{
	if(x==arr[x])
	{
		return x;
	}
	else
	{
		return arr[x]=find(arr[x]);
	}
}
void unite(int x,int y)
{
	x=find(x);
	y=find(y);
	if(x==y)
	{
		return;
	}
	if(rank[x]<rank[y])
	{
		arr[x]=y;
	}
	else
	{
		arr[y]=x;
		if(rank[x]==rank[y])
		{
			rank[y]++;
		}
	}
}
int kruskal(int n,int m)
{
	int result=0,n_edge=0,f1,f2,j=1;
	for(int i=1; i<=m; i++)
	{
		f1=find(arr[a[i].edga_first]);
		f2=find(arr[a[i].edga_second]);
		if(f1!=f2)
		{
			unite(f1,f2);
			result+=a[i].e;
			n_edge++;
		}
		if(n_edge==n-1)
		{
			return result;
		}
	}
	return -1;
}
int main()
{
	int n,m,p,q,ans;
	printf("请输入当前的节点总数和已知条件数:\n"); 
	scanf("%d%d",&n,&m);
	Init(n);
	printf("分别按照边1,边2,权值的方式进行输入,总共输入%d条:\n",m);
	for(int i=1; i<=m; i++)
	{
		scanf("%d%d%d",&a[i].edga_first,&a[i].edga_second,&a[i].e);
	}
	sort(m);
	p=kruskal(n,m);
	if(p==-1)
	{
		printf("无法生成最小生成树\n");
	}else{
		printf("最小生成树的总权值为:%d\n",p);
	}
	return 0;
}

/*
测试样例
6 10
1 3 4
1 2 3
1 6 1
6 2 5
6 5 3
2 3 2
2 4 4
5 4 7
4 3 6
5 2 5
*/

给一个样例图:

 

 

最小生成树如下:

 

 

 代码实测运行图:

 

普利姆算法:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/91181.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Python计算机毕业设计高校教学过程管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

产品诚可贵,质量价更高

产品诚可贵&#xff0c;质量价更高缘起所属行业研发人员规模所在团队规模团队开发模式产品类别软件主体层次软件交付周期软件需求质量/感受/问题设计质量保证及好与不好开源组件代码质量千行缺陷数单元测试代码覆盖率和测试质量质量文化和QA人员测试团队人员配置质量工程活动功…

第4篇:嵌入式Linux应用开发基础知识

嵌入式Linux应用开发基础知识一、GCC编译过程二、MakefileMakefile的引入及规则Makefile的语法a. 通配符b. 假想目标: .PHONYC. 变量Makefile函数函数foreach函数filter/filter-outWildcardpatsubst函数Makefile实例通用MakefikeMakefikeMakefile.build说明.txt三、TCPserver.c…

springMVC+mysql实现的Java web图书管理系统源码+运行教程+参考论文

今天给大家演示的是一款由srpingMVC实现的Java web图书管理系统&#xff0c;本项目功能非常丰富&#xff0c;且附带配套论文及视频指导配置运行教程&#xff0c;系统实现的功能主要有&#xff1a;图书馆里、图书分类管理、出版社管理、图表图书统计展示、用户管理、角色管理、权…

小村庄迸发大能量,桃浦村“藏”着花样经,“烘”出财富来

从几人的小公司到产税千万级的高新技术和数集团企业总部;从拿着10万元注册资金开公司处处碰壁的小公司到家喻户晓的国牌护肤品林清轩……在普陀区桃浦镇的桃浦村&#xff0c;默默“耕耘”出了一家家优秀的民营企业。 筑巢引凤聚人才&#xff0c;注入乡村振兴新动能。在上海市委…

【数据结构】二叉树的前序遍历、中序遍历、后序遍历、层序遍历

文章目录 1.二叉树的概念 1.1概念 1.2存储方式 1.3特殊的二叉树 1.4规律 2.二叉树的实现 2.1表现方式 2.2遍历 2.2.1前序遍历 思想 代码 详细分析 2.2.2中序遍历 2.2.3后序遍历 2.2.4层序遍历 思想 代码 详细过程 1.二叉树的概念 1.1概念 一棵二叉树是结点的一个有限…

第25届京港会开幕 元宇宙产业委与香港国际元宇宙协会启动全面合作

央链直播讯&#xff0c;以“融入新格局 合作谱新篇”为主题的第25届北京香港经济合作研讨洽谈会&#xff08;简称“京港洽谈会”&#xff09;14日在北京和香港开幕。据悉&#xff0c;自1997年香港回归以来&#xff0c;京港洽谈会已成功举办24届&#xff0c;两地在金融、专业服务…

基于 KubeSphere 的运管系统落地实践

作者&#xff1a;任建伟&#xff0c;某知名互联网公司云原生工程师&#xff0c;容器技术信徒&#xff0c;云原生领域的实践者。 背景介绍 在接触容器化之前&#xff0c;我们团队内部的应用一直都是基于虚拟机运管&#xff0c;由开发人员自行维护。 由于面向多开发部门服务&am…

ThingsBoard 3.1.1版本在window本地运行之TB-Gateway ODBC数据上传(四)

目录 1、前言 2、Thingsboard Gateway 1.tb-gateway的概念 2.tb-gateway的配置 3.odbc连接器配置 3、ODBC的配置 1.安装window的ODBC驱动程序 2.配置ODBC的驱动程序信息 4、效果展示 1、前言 项目中会出现这样的情况&#xff0c;有个平台搭建在本地&#xff0c;而数据也存…

Jenkins构建并部署一个go语言项目

Jenkins安装 1、下载 安装java [rootlocalhost ~]# yum install java-1.8.0-openjdk* -y 方式一&#xff1a; #下载安装包 [rootlocalhost ~]# wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat-stable/jenkins-2.249.1-1.1.noarch.rpm #安装Jenkins [rootlocalhost…

【excel导入、导出】pom、实体类、工具类、例子

目录 一、环境搭建&#xff1a; pom&#xff1a; 实体类&#xff08;ExcelClassField &#xff09;&#xff1a; 工具类&#xff1a; 二、【示例】导入 controller&#xff1a; service 实体类&#xff1a; 注意&#xff1a; 三、【示例】导出 controller&#xff1a; …

搜索与图论 - bellman-ford 算法

文章目录一、为什么 Dijkstra 算法不适用于含负权的图1. 理论推导2. 实例演示2.1 详细步骤2.2 结果二、bellman-ford 算法1. 简介2. 基本思路3. 简单举例4. bellman-ford 算法具体实现过程详见例题有边数限制的最短路。三、bellman-ford 算法例题——有边数限制的最短路具体实现…

仓库24代 “ CK_Label_v24

产品型号 CK_Label_v24 尺寸 124x90x12mm&#xff08;不含安装支架&#xff09; 屏幕尺寸 4.2 inch 显示技术 电子墨水屏显示 显示区域面积 (mm) 84.8(H) x 63.6(V) 分辨率 400*300 像素密度 120dpi 显示颜色 黑/白 外观颜色 白色&灰外圏 按键 3 指示灯…

【C++】STL标准模板库

目录 一、概念 STL的四种基本组件 容器vector 迭代器iterator 函数对象function object 算法algorithm 二、使用 容器vector的使用 泛型程序设计&#xff1a; 所谓泛型程序设计就是编写不依赖于具体数据类型的程序。C中&#xff0c;模板就是泛型程序设计的主要…

一次疑似 JVM native 内存泄漏的排查实录

最近开发同学反馈&#xff0c;某定时任务服务疑似有内存泄漏&#xff0c;整个进程的内存占用比 Xmx 内存大不少&#xff0c;而且看起来是缓慢上升的&#xff0c;做了下面这次分析&#xff0c;包括下面的内容&#xff1a; 分析 JVM native 内存的一些常见思路内存增长了&#x…

关于Arduino连接L298N供电问题

关于Arduino连接L298N供电问题 查看原文 该L298N板声称有一个5V稳压器为Arduino供电&#xff0c;在这种情况下&#xff0c;您可以使用单个电源&#xff0c;并让电机板为Arduino供电。 关于为Arduino和电机提供动力有两种思想流派&#xff1a; 使用两个独立的电源&#xff0…

NumPy 的使用

NumPy&#xff08;Numerical Python&#xff09;是Python 语言的一个扩展程序库&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;同时也针对数组运算提供大量的数学函数库。 NumPy 的前身 Numeric 最早由 Jim Hugunin 与其他协作者共同开发&#xff0c;2005 年&#xff0…

百万千万爆款视频的脚本是怎么写出来的?两套模板教你做同款

那些百万千万爆款视频的脚本是怎么写出来的&#xff1f;两套模板教你做同款。 每天都能刷到百万赞的短视频&#xff0c;看看自己的视频点赞量&#xff0c;失落是一种感觉&#xff0c;其实你也可以做出优秀的爆款文案。 今天给大家介绍两种短视频脚本模板&#xff0c;大家可以…

idea手动创建干净的maven项目,很简单

大家好&#xff0c;今天我们分享使用idea开发工具创建干净的maven项目 这是Maven的官网&#xff1a; 点一下就可以 首先&#xff0c;我们来了解一下什么是Maven&#xff0c;就是说关于Maven这个东西你要知道的是 1.Maven是一个跨平台&#xff08;在很多平台上都可以使用&…

B4:Unity制作Moba类游戏——小兵AI系统

若想取得战争的胜利&#xff0c;必先控好兵线。 ———— 麦克阿瑟 是时候让敌人经历一下我们兵线的洗礼。 ———— 拿破仑 在LOL对局中&#xff0c;职业选手对兵线的控制可以说是达到了“运筹帷幄之中,决胜千里之外”。其实普通玩家只要控好兵线&#xff0c;在对线中一样可以…