Kruskal算法求最小生成树

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX 100
#define NO INT_MAX//NO表示没有边,相当于INF

typedef struct Graph
{
	int arcnum;
	int vexnum;
	char vextex[MAX][20];
	int martrix[MAX][MAX];
}Graph;
//邻接矩阵打印输出图
void print_graph(Graph* g)
{
	for (int i = 0; i < g->vexnum; i++)
	{
		printf("\t%s", g->vextex[i]);
	}
	printf("\n");
	for (int i = 0; i < g->vexnum; i++)
	{
		printf("%s\t", g->vextex[i]);
		for (int j = 0; j < g->vexnum; j++)
		{
			if (g->martrix[i][j] == INT_MAX)
			{
				printf("∞\t");
			}
			else
			{
				printf("%d\t", g->martrix[i][j]);
			}
		}
		printf("\n");
	}
}
//定义最小生成树的边结构
typedef struct Arc
{
	int begin;
	int end;
	int weight;//在边结构中加多了一个权值weight来用于判断构造最小生成树
}Arc;
//打印最小生成树
void print_tree(Graph* g, Arc* arc, int count)
{
	printf("最小生成树:\n");
	for (int i = 0; i < count; i++)
	{
		printf("%s--->%s\n", g->vextex[arc[i].begin], g->vextex[arc[i].end]);
	}
}
//比较函数(用于在qsort中,因为qsort是一个泛函数,开始时未知函数类型,需要在调用函数时再给出),
//所以这个比较基准函数需要使用强制类型转换
int compare_arc(const void* a, const void* b)
{
	return(((Arc*)a)->weight-((Arc*)b)->weight);//强制转化为arc类型,根据边结构的weight值进行比较,如果大于则返回正数,等于则返回0,小于则返回负数
}
//克鲁斯卡尔算法
void graph_kruskal(Graph* g)
{
	//定义边结构数组arc用于保存图中存在的边
	Arc* arc = (Arc*)malloc(sizeof(Arc) * g->vexnum * g->vexnum);
	assert(arc);
	int count=0;//count用于存边
	for (int i = 0; i < g->vexnum; i++)
	{
		for (int j = 0; j < g->vexnum; j++)
		{
			if (g->martrix[i][j] != NO)
			{
				(arc + count)->begin = i;
				(arc + count)->end = j;
				(arc + count)->weight = g->martrix[i][j];
				count++;
			}
		}
	}
	//快速排序根据边权值进行排序
	//(注意快速排序是不稳定的,所以选边的顺序不是按照原顺序的)
	qsort(arc,count,sizeof(Arc),compare_arc);
	//定义parent整型数组,大小为顶点数
	int* parent = (int*)malloc(sizeof(int) * g->vexnum);
	assert(parent);
	for (int i = 0; i < g->vexnum; i++)
	{
		parent[i] = i;//初始化时先将每个结点的前驱结点都置为自身
	}
	Arc* result = (Arc*)malloc(sizeof(Arc) * g->arcnum);//result是用于存储对边进行排序后的边结构 
	assert(result);
	count = 0;//count用于跟踪已选的边的数量
	int i = 0;//i用于遍历所有的边
	printf("Kruskal的选边过程如下:\n");
	while (count < g->vexnum - 1)//当边没选够时则继续进行
	{
		int x = (arc + i)->begin;
		int y = (arc + i)->end;
		//初始化两个变量来存x和y的根节点
		int root_x = x;
		int root_y = y;
		while (parent[root_x] != root_x)
		{
			root_x = parent[root_x];//进行压缩路径,将其根节点设为根节点的根节点
		}
		while (parent[root_y] != root_y)
		{
			root_y = parent[root_y];
		}
		if (root_x != root_y)//如果不构成一个环的话
		{
			result[count] = arc[i]; //将该边加入到最小生成树中
			count++;
			printf("选择边:%s---%s,权值为:%d\n",g->vextex[x],g->vextex[y],g->martrix[x][y]);
			parent[root_x] = root_y;//将所选边前面点的前驱节点置为后边的点(也是起到类似压缩路径的效果,谁先谁后好像关系不大)
		}
		i++;
	}
	print_tree(g, arc, count);
	free(arc);
	free(result);
	free(parent);
}

int main()
{
	Graph g = { 10,7,{"A","B","C","D","E","F","G"},
		{
			{NO,50,60,NO,NO,NO,NO},
			{50,NO,NO,65,40,NO,NO},
			{60,NO,NO,52,NO,NO,45},
			{NO,65,52,NO,50,30,42},
			{NO,40,NO,50,NO,70,NO},
			{NO,NO,NO,30,70,NO,NO},
			{NO,NO,45,42,NO,NO,NO}
		} };
	print_graph(&g);
	graph_kruskal(&g);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用node将页面转为pdf?(puppeteer实现)

本文章适合win系统下实验&#xff08;linux&#xff0c;mac可能会出现些莫名其妙的bug我也不会解决&#xff09; 具体过程 首先了解什么时无头浏览器启动无头浏览器打开指定的url页面设置导出pdf格式开始转化完整基础代码 首先了解什么时无头浏览器 没有界面的浏览器下载pupp…

SLC Flash SD芯片:高性能存储的优选

SLC Flash SD芯片是一种采用单阶存储单元&#xff08;SingleLevel Cell&#xff0c;SLC&#xff09;技术的Secure Digital&#xff08;SD&#xff09;存储卡。SLC技术以其快速的传输速度、低功耗和较长的存储单元寿命而闻名。 MK米客方德 SLC Flash的优势 1. 快速的传输速度&a…

如何确定一段文字的语言?(语种识别模型推荐)

个人用下来&#xff0c;感觉fasttext很好用&#xff0c;相对比较准确。 https://pypi.org/project/fasttext-langdetect/

太阳能语音警示杆在户外的应用及其作用

一、太阳能语音警示杆的主要应用领域 交通管理&#xff1a;在城市道路、乡村公路、高速公路等交通要道&#xff0c;太阳能语音警示杆可以用于提醒驾驶员注意前方路况、减速慢行或者避让施工区域。例如&#xff0c;在临时施工路段&#xff0c;警示杆可以播放“前方施工&#xf…

Qt——升级系列(Level Two):Hello Qt 程序实现、项目文件解析、Qt 编程注意事项

Hello Qt 程序实现 使用“按钮”实现 纯代码方式实现&#xff1a; // Widget构造函数的实现 Widget::Widget(QWidget *parent): QWidget(parent) // 使用父类构造函数初始化QWidget&#xff0c;传入父窗口指针, ui(new Ui::Widget) // 创建Ui::Widget类的实例&#xff0c;并…

Qt图标字体文件中提取字体保存为图片

本文借用别人写的一个IconHelper来做说明。 1. 加载一个字体文件 QScopedPointer<IconHelper> iconHelper(new IconHelper(":/fa-regular-400.ttf", "Font Awesome 6 Pro Regular"));构造函数 IconHelper::IconHelper(const QString &fontFile…

大模型产品层出不穷,如何慧眼识珠?

先预祝亲爱的读者们“端午安康“ 大模型百花齐放&#xff0c;选择难上加难 面对眼前层出不穷的大模型产品&#xff0c;许多人会不禁感到困惑&#xff1a;哪个才是真正适合自己的爆款大模型?在中国本土 alone&#xff0c;就有百来个大模型产品&#xff0c;简直是五花八门&…

C语言指针介绍其二

指针运算 指针-整数 指针-整数有一个常见的作用&#xff1a;用指针打印数组的内容 int main() {int arr[10];int* p arr;for (int i 0; i < 10; i){arr[i] i;}for (size_t i 0; i < 10; i){printf("%d ", *(p i));} } 这里我们可以探索到许多方法&…

选择虚拟制作的三大理由!虚幻引擎制作 vs 传统影视制作

影视制作一直是一个充满创意但耗时复杂的过程&#xff0c;通常以线性方式进行。然而&#xff0c;随着虚幻引擎5的不断完善&#xff0c;越来越多的影视制作人开始拥抱虚幻引擎制作所带来的灵活性和艺术自由。近年来&#xff0c;一些备受瞩目的影视作品&#xff0c;如&#xff1a…

现代社区管理中的电瓶车违停检测技术

随着城市化进程的加快&#xff0c;电瓶车作为一种环保、便捷的出行工具在社区内的使用越来越普及。然而&#xff0c;电瓶车的随意停放问题也日益严重&#xff0c;影响了社区的整体环境和居民的生活质量。为了解决这一问题&#xff0c;社区管理者迫切需要一种高效、准确的电瓶车…

【Vue】项目目录介绍和运行流程

文章目录 一、项目目录介绍二、public/index.html三、src/main.js四、运行流程 一、项目目录介绍 虽然脚手架中的文件有很多&#xff0c;目前咱们只需认识三个文件即可&#xff0c;这三个文件就决定了我们项目的运行 main.js 入口文件App.vue App根组件index.html 模板文件 我…

course-nlp——6-rnn-english-numbers

本文参考自https://github.com/fastai/course-nlp。 使用 RNN 预测数字的英文单词版本 在上一课中&#xff0c;我们将 RNN 用作语言模型的一部分。今天&#xff0c;我们将深入了解 RNN 是什么以及它们如何工作。我们将使用尝试预测数字的英文单词版本的问题来实现这一点。 让…

安全测试 之 安全漏洞 CSRF

1. 背景 安全测试是在功能测试的基础上进行的&#xff0c;它验证软件的安全需求&#xff0c;确保产品在遭受恶意攻击时仍能正常运行&#xff0c;并保护用户信息不受侵犯。 2. CSRF 定义 CSRF&#xff08;Cross-Site Request Forgery&#xff09;&#xff0c;中文名为“跨站请…

Xmind Pro 2024 专业版激活码(附下载链接)

说到思维导图&#xff0c;就不能不提 Xmind。这是一款优秀的思维导图工具&#xff0c;拥有着丰富的导图模板&#xff0c;漂亮的界面和配色&#xff0c;以及各种各样的创意工具。 新架构速度更快 采用全新 Snowdancer 引擎&#xff0c;一种堪称「黑科技」的先进图形渲染技术。…

JDK17 AQS源码分析

AQS 概览AQS官方解释简单来说 JDK17 中 AQS源码分析Lock 阶段UnLock 阶段什么时候取消排队呢&#xff1f; 在学习阳哥的 JUC课程的时候&#xff0c;阳哥讲AQS用的是JDK8&#xff0c;我用的是JDK17&#xff0c;想着自己分析一下&#xff0c;分析完之后发现JDK17与JDK8还是有些不…

Linux系统之fc命令的基本使用

Linux系统之fc命令的基本使用 一、fc命令介绍1.1 fc命令简介1.2 fc命令用途 二、fc命令的帮助信息2.1 fc的man帮助2.2 fc命令的使用帮助2.3 fc命令与history命令区别 三、fc命令的基本使用3.1 显示最近执行的命令3.2 指定序号查询历史命令3.3 使用vim编辑第n条历史命令3.4 替换…

ElementUI之el-tooltip显示多行内容

ElementUI之el-tooltip显示多行内容 文章目录 ElementUI之el-tooltip显示多行内容1. 多行文本实现2. 实现代码3. 展示效果 1. 多行文本实现 展示多行文本或者是设置文本内容的格式&#xff0c;使用具名 slot 分发content&#xff0c;替代tooltip中的content属性。 2. 实现代码 …

JAVA-学习-2

一、类 1、类的定义 把相似的对象划分了一个类。 类指的就是一种模板&#xff0c;定义了一种特定类型的所有对象的属性和行为 在一个.java的问题件中&#xff0c;可以有多个class&#xff0c;但是智能有一个class是用public的class。被声明的public的class&#xff0c;必须和文…

【CTF-Web】文件上传漏洞学习笔记(ctfshow题目)

文件上传 文章目录 文件上传What is Upload-File&#xff1f;Upload-File In CTFWeb151考点&#xff1a;前端校验解题&#xff1a; Web152考点&#xff1a;后端校验要严密解题&#xff1a; Web153考点&#xff1a;后端校验 配置文件介绍解题&#xff1a; Web154考点&#xff1a…

ChatTTS webUI API:ChatTTS本地网页界面的高效文本转语音、同时支持API调用!

原文链接&#xff1a;&#xff08;更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号&#xff01;&#xff09; ChatTTS webUI & API&#xff1a;ChatTTS本地网页界面的高效文本转语音、同时支持API调用&#xff01; &#x1f31f;一个简单的本地网…