克鲁斯卡尔算法最小生成树--C语言

        同样是最小生成树,普利姆算法是从一个起始顶点开始,逐步扩展生成树,每次选择连接生成树和未包含顶点的最小边。而克鲁斯卡尔算法是按权值排序的方式,从最小的边开始逐步添加到生成树中,确保不会形成环,直到生成树包含所有顶点。

假设我有下面的一个图,克鲁斯卡尔算法就是把这些带权值的边进行排序,然后添加到树中并确保不会成环。

第一步:首先遍历所有边,记录边的前驱和后继(判断是否有环会使用到),并进行排序,这里只列举了全三个边。

第二步:将边添加到树(直接打印前驱后继顶点和权值即可),检查是否有环,这一步该如何实现?

        有环的情况如下,假设 0->2 是最先加入到树的边,其次是 2->1 ,最后是 1->0 ,因为 0 是 2 的前驱,2 是 1 的前驱,那么我们可以让 0 是 1 的前驱,这样我们只需要检查 1 的后继是不是等于前驱即可,结果是等于,所以不能纳入。

        可以这样理解:0->2 是链表,2->1 增加了链表的长度,但是1,2都属于 0 这个头节点的集合,所以当新链加入时要判断新练的尾节点是否是头节点,如果是,就说明链表有环。

以上可以用结构体来实现。

第三步:遍历第二步,遍历一共 图的边数 次。

接下来是代码部分:

首先是结构体 边(Edge) 的构建:然后创建一个数组用于存放这些边,并且对边进行初始化。

        我们可以观察到边的二维数组是关于正对角线对称的,这是因为无向图权值会出现两次,例如:0->1 和1->0 都是 6,所以我们只需要在正对角线的一侧来寻找边即可,如果在整个图中寻找边最后会找到两组相同的边。这也是为什么 for 循环的条件一个是 i 一个是 i+1。

typedef struct Edge {int start;int end;int weight;
}Edge;Edge* EdgeInit(Graph* G) {int index = 0;Edge* E = (Edge*)malloc(sizeof(Edge) * G->arcsNum);for (int i = 0; i < G->vexsNum; i++) {for (int j = i + 1; j < G->vexsNum; j++) {if (G->arcs[i][j] != Max) {E[index].start = i;E[index].end = j;E[index].weight = G->arcs[i][j];index++;}}}return E;
}

接着是边的排序:这里是简单的冒泡排序,让边数组的顺序根据权值大小从小到大排序。

void Edgesort(Edge* E,Graph* G) {for (int i = 0; i < G->arcsNum; i++) {for (int j = i + 1; j < G->arcsNum; j++) {if (E[j].weight < E[i].weight) {Edge tmp ;tmp = E[i];E[i] = E[j];E[j] = tmp;}}}
}

最后是函数主体:

1.connected数组是存顶点的前驱节点,用来表示该顶点在哪个顶点的集合内(相当于链表的头节点)。第一个for循环初始化该数组,因为初始前驱节点都是本身。
2.第二个for循环是为了遍历每条边,如果边的前驱和后继相等,那么不打印也即是不纳入树。
3.第三个for循环是更新connected数组,更新顶点的前驱节点。

void Kurskal(Edge* E, Graph* G) {Edgesort(E,G);int* connected = (int*)malloc(sizeof(int) * G->vexsNum);for (int i = 0; i < G->vexsNum; i++) {connected[i] = i;}for (int j = 0; j < G->arcsNum; j++) {int start = connected[E[j].start];int end = connected[E[j].end];if (start != end) {printf(" %c -> %c ,weight = %d", G->vexs[start], G->vexs[end], E[j].weight);printf("\n");for (int a = 0; a < G->arcsNum; a++) {if (connected[a] == end ) {connected[a] = start;}}}}
}

下面看一个例子用来理解最后一个for循环:

        首先最小的是 0->2 边,权值为1。那么就会打印 0->2,然后更新connected数组:由左图变成右图,把connected[2]更新为connected[0],也就是说 2 的前驱是 0 ,那么它就在 0 的集合内(链表内)。

 

        假设说现在又有 2->1 边进入,那么connected数组变化如下:这时的start是0,end是1,把connected[1]的值更新为connected[2],表示纳入该集合(链表)。

        现在又有一个边 1->0 进入,现在connected[1]和connected[0]的位置都是0,也就是start等于end,这时还纳入就会造成成环问题,所以不进入if语句,不进入树。

以上就是最后一个for循环的解释。

这就是文章的全部内容了,希望对你有所帮助,如有错误欢迎指出。

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

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

相关文章

自友科技破解走班教育排课难题

新高考后&#xff0c;校园教务都面临着晋级&#xff0c;其中走班教育的分班排课是个巨大的挑战。 所以在分班排课的时候要清楚一下几个问题 一是&#xff1a;清楚的核算学生的选考科目。学生选科提交后做好并承认&#xff0c;最好是在分班后不要改或很少的一部分人改动。 二是…

达梦8 探寻达梦排序原理:传统排序机制(SORT_FLAG=0)

测试版本&#xff1a;--03134283938-20221019-172201-20018 达梦的排序机制由四个dm.ini参数控制&#xff1a; #maximum sort buffer size in Megabytes &#xff0c;有效值范围&#xff08;1~2048&#xff09; SORT_BUF_SIZE 100 #ma…

SpringBoot: 启动流程和类装载

前面我们学过Spring定制了自己的可执行jar&#xff0c;将真正执行时需要的类和依赖放到BOOT-INF/classes、BOOT-INF/lib来&#xff0c;为了能够识别这些为止的源文件&#xff0c;Spring定制了自己类加载器&#xff0c;本节我们来讲解这个类加载器。本节涉及的内容主要包括: Sp…

Linux部署调度工具xxl-job

背景&#xff1a; Pentaho Data Integration&#xff08;kettle&#xff09;作为用户规模最多的开源ETL工具&#xff0c;强大简洁的功能深受广大ETL从业者的欢迎。但kettle本身的调度监控功能却非常弱。Pentaho官方都建议采用crontab(Unix&#xff0c;linux平台)和计划任务(Win…

群体优化算法----树蛙优化算法介绍以及应用于资源分配示例

介绍 树蛙优化算法&#xff08;Tree Frog Optimization Algorithm, TFO&#xff09;是一种基于群体智能的优化算法&#xff0c;模拟了树蛙在自然环境中的跳跃和觅食行为。该算法通过模拟树蛙在树枝间的跳跃来寻找最优解&#xff0c;属于近年来发展起来的自然启发式算法的一种 …

抽象的java入门1.3.2

前言&#xff1a; 全新版本的函数&#xff08;方法&#xff09;定义&#xff0c;更简单 1.优化了验证过程&#xff0c;直击本质 2.新增目前一图流 正片&#xff1a; 函数的结构可以分为三部分&#xff1a;函数名&#xff0c;参数&#xff0c;函数体 一生二&#xff0c;二生…

6.9总结

Vue生命周期 生命周期&#xff1a;指一个对象从创建到销毁的整个过程生命周期的八个阶段&#xff1a;每触发一个生命周期事件&#xff0c;会自动执行一个生命周期的方法&#xff08;钩子&#xff09; mounted&#xff1a;挂载完成&#xff0c;Vue初始化成功&#xff0c;HTML渲…

ssm629基于SSM的二手交易平台设计与开发+jsp【已测试】

前言&#xff1a;&#x1f469;‍&#x1f4bb; 计算机行业的同仁们&#xff0c;大家好&#xff01;作为专注于Java领域多年的开发者&#xff0c;我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源&#xff1a; &#x1f469;‍&#x1f4bb; SpringBoot…

智慧社区整体解决方案

1.智慧社区整体建设方案内容 2.整体功能介绍

linux动态调试 dev_dbg

动态调试使用方法 打开内核动态调试开关&#xff0c;make menuconfig选中CONFIG_DYNAMIC_DEBUG以及CONFIG_DEBUG_FS Linux启动后&#xff0c;使用命令行挂载上dbgfs 1. mkdir /mnt/dbg 2. mount -t debugfs none /mnt/dbg 1.控制某个文件所有dev_dbg()&#xff0c; echo -n &q…

sqli-labs 靶场 less-11~14 第十一关、第十二关、第十三关、第十四关详解:联合注入、错误注入

SQLi-Labs是一个用于学习和练习SQL注入漏洞的开源应用程序。通过它&#xff0c;我们可以学习如何识别和利用不同类型的SQL注入漏洞&#xff0c;并了解如何修复和防范这些漏洞。Less 11 SQLI DUMB SERIES-11判断注入点 尝试在用户名这个字段实施注入,且试出SQL语句闭合方式为单…

电子阅览室有何作用

随着互联网的快速发展&#xff0c;电子阅览室逐渐成为人们获取知识的新方式。它为读者提供了便捷、高效的阅读体验&#xff0c;具有诸多作用。首先&#xff0c;电子阅览室拥有丰富的电子书籍资源&#xff0c;涵盖了各个领域的知识。无论是文学作品还是学术论文&#xff0c;读者…

解决Win10系统ping不通、无法远程的问题

1、概述 某天要使用微软的远程桌面程序mstsc.exe远程到旁边的一台测试电脑上,结果远程不了,ping都ping不通,于是详细研究了这个问题。在此大概地记录一下该问题排查的过程,以供参考。 2、ping不通 使用mstsc.exe远程到测试电脑,远程不了,没有反应。于是手动ping一…

英语学习笔记33——A fine day

A fine day 风和日丽 词汇 Vocabulary day n. 日子&#xff0c;白天 复数&#xff1a;days 常见节日&#xff1a;Mothers’ Day 母亲节      Fathers’ Day 父亲节      Teachers’ Day 教师节      Children’s Day 儿童节      Women’s Day 妇女节 c…

html--宇航员404

<!doctype html> <html> <head> <meta charset"utf-8"> <title>太空404</title><style> html {margin: 0;padding: 0;background-color: white; }body, html {width: 100%;height: 100%;overflow: hidden; }#svgContainer…

【数据库】SQL--DDL(初阶)

文章目录 DDL1. 数据库操作1.1. 表操作1.1.1 创建1.1.2. 查询 2. 数据类型及案例2.1 数值类型2.2 字符串类型2.3 日期时间类型2.4 案例练习 3. 表操作--修改3.1 添加字段3.2 修改字段3.3 修改表名 4. 表操作-删除4.1 删除字段4.2 删除表 5. DDL小结 更多数据库MySQL系统内容就在…

Pytorch 实现目标检测二(Pytorch 24)

一 实例操作目标检测 下面通过一个具体的例子来说明锚框标签。我们已经为加载图像中的狗和猫定义了真实边界框&#xff0c;其中第一个 元素是类别&#xff08;0代表狗&#xff0c;1代表猫&#xff09;&#xff0c;其余四个元素是左上角和右下角的(x, y)轴坐标&#xff08;范围…

【网络安全】【深度学习】【入侵检测】SDN模拟网络入侵攻击并检测,实时检测,深度学习

文章目录 1. 前言2. Mininet 和 Ryu 的区别2.1 Mininet2.2 Ryu2.3 总结 3. 模拟攻击3.1 环境准备3.2 创建 Mininet 网络拓扑3.2 启动 Ryu 控制器3.3 模拟网络攻击3.4 捕获流量 4. 实时异常检测4.1 在 Ryu 控制器中4.2 在 h2 机器上的实验结果4.3 深度学习模型部署上h2机器 帮助…

电感十大供应商

电感品牌-电感器品牌排行榜-电感十大品牌-Maigoo品牌榜

Fences 5 激活码 - 电脑桌面整理软件

提起桌面整理&#xff0c;经典老牌工具 Fences 必有一席之地&#xff0c;Stardock 发布了最新的 Fences 5 版本。 可以将文件和图标归类放入各个栅栏分区&#xff0c;并支持文件夹展开至桌面、分区置顶、淡化隐藏图标等功能&#xff0c;能让你的桌面焕然一新&#xff0c;不再混…