有点混乱的普里姆算法求最小生成树

在这里插入图片描述

Graph.h

#pragma once
//邻接矩阵的创建
#include<stdio.h>
#include <stdlib.h>  
#include<assert.h>
#include<string.h>
#include<stdbool.h>
#include<limits.h>
#define MAX 100
#define INF INT_MAX
typedef struct Graph
{int n;//顶点数char vertex[MAX];//用字符数组来存储顶点int edges[MAX][MAX];//邻接矩阵,存储边的权值。//(因为为无向带权图,若为自身则权值设为0,相互之间则设为权值,无边的话就设为无穷)
}Graph;//声明
//获取给出字符(串)其所在顶点集(数组)的下标
int get_pos(Graph* g, char ch);
//图的创建
void CreateGraph(Graph*& G,int n);
// 输出图的邻接矩阵
void PrintGraph(Graph * g);
//图的销毁
void DestroyGraph(Graph* g);

functions.cpp

#include"Graph.h"
//获取给出字符(串)其所在顶点集(数组)的下标
int get_pos(Graph* g,char ch)
{for (int i = 0; i < g->n; i++){if (ch==g->vertex[i]){return i;}}return -1;
}//图的创建
void CreateGraph(Graph*&G,int n)//n为顶点数
{G= (Graph*)malloc(sizeof(Graph));assert(G);//判断是否成功开辟空间G->n = n;for (int i = 0; i < G->n; i++){for (int j = 0; j < G->n; j++){if (i == j){G->edges[i][j] = 0;G->edges[j][i] = 0;}else//一开始默认全都是相互之间没有边{G->edges[i][j] = INF;G->edges[j][i] = INF;}}}}
//输出图的邻接矩阵
void PrintGraph(Graph* g)
{for (int i = 0; i < g->n; i++){printf("\t%c", g->vertex[i]);}printf("\n");for (int i = 0; i < g->n; i++){printf("%c\t", g->vertex[i]);for (int j = 0; j < g->n; j++){if (g->edges[i][j] == INF){printf("∞\t");continue;}printf("%d\t", g->edges[i][j]);}printf("\n");}
}
//图的销毁
void DestroyGraph(Graph* g)
{free(g);
}

算法

#include"Graph.h"
//无向带权图
//#########(普里姆算法求最小生成树)#################
//返回最小权值邻接边的点的下标
int minKey(int key[], int mstSet[], Graph* G)//key数组是用来存最小边权值的数组
//mstSet 是在普里姆(Prim)算法中使用的一个辅助数组,全称可以理解为 "Minimum Spanning Tree Set",即“最小生成树集合”
{int min = INF;int min_index = 0;//用于记录邻接最小权值边终点的下标for (int i = 0; i < G->n; i++){if (mstSet[i] == 0 && key[i] < min)//如果该点没有被加入最小生成树集合并且存在边的话则将其边权值赋给min并且将其下标赋给min_index{min = key[i];min_index = i;}}return min_index;
}
//打印最小生成树
void PrintMST(int parent[], Graph* G)
{printf("最小生成树构成:\n");for (int i = 1; i < G->n; i++)//i要从1开始,因为第一个顶点没有前驱节点{printf("边<%c,%c>权为:%d\n", G->vertex[parent[i]], G->vertex[i], G->edges[parent[i]][i]);}
}
//打印最小生成树
void PrintMST2(int parent[], Graph* G,int sequence[])
{printf("最小生成树构成:\n");for (int i = 0; i < G->n-1; i++)//这里是要小于n-1,因为sequence里有n-1个节点{printf("边<%c,%c>权为:%d\n", G->vertex[parent[sequence[i]]],G->vertex[sequence[i]],G->edges[parent[sequence[i]]][sequence[i]]);}
}
//完整普里姆算法
void PrimMST(Graph* G)
{int parent[MAX] = {0};//用于记录最小生成树的路径int key[MAX];int mstSet[MAX];//先初始化好key数组和mstSet数组for (int i = 0; i < G->n; i++){key[i] = INF;mstSet[i] =0;//均设为0表示均未被加入最小生成树集合}//一开始都做好了初始化,但为了能达到循环进行的目的要先对第一个点进行特殊处理key[0] = 0;// 从顶点0开始构造最小生成树parent[0] = -1;//因为最小生成树的第一个顶点没有父母节点int sequence[MAX];//用于记录顺序int j = 0;int n = 0;//n用于计数for (int i = 0; i < G->n-1; i++)//i用于循环控制次数,条件为小于顶点数减一,因为每次处理都可简化为存父节点和找邻接最小边,而最小生成树是前n-1个顶点为父节点{int u = minKey(key, mstSet, G);//u用于存储邻接最小边点的下标mstSet[u] = 1;//将该点标记为已加入最小生成树集中n++;if (u != 0){sequence[j++] = u;}//找下一个邻接最小权值边的顶点,设好其前驱节点即 // 更新相邻顶点的key值和parent值for (int i = 0; i < G->n; i++){if (G->edges[u][i] && mstSet[i] == 0 && G->edges[u][i] < key[i])//若边不是指向自身并且点没有被加入到最小生成树集合中并且存在边{//则设好其父母结点并将边权值赋值给key[i]parent[i] = u;key[i] = G->edges[u][i];//赋值好所有相邻边的权值}}}//这部分用于判断哪个顶点不存在于sequence数组中,把它找出来,就是最后一个顶点。再加入到sequence中int temp;int flag = 0;for (int i = 1; i < G->n; i++){int n = 0;for (int j = 0; j < G->n - 1; j++){if (sequence[j] == i){break;}else{n++;}if (n == G->n - 1){temp = i;flag = 1;break;}}if (flag == 1){break;}}sequence[j] = temp;//把最小生成树的最后一个结点加入到顺序数组中PrintMST2(parent, G,sequence);
}int main(int argc, char* argv[])
{Graph*G;CreateGraph(G,7);char V[8] = "ABCDEFG";for (int i = 0; i < G->n; i++){G->vertex[i] = V[i];//将顶点存进图中}G->edges[get_pos(G, 'A')][get_pos(G, 'B')] = 50;G->edges[get_pos(G, 'B')][get_pos(G, 'A')] = 50;G->edges[get_pos(G, 'B')][get_pos(G, 'D')] = 65;G->edges[get_pos(G, 'D')][get_pos(G, 'B')] = 65;G->edges[get_pos(G, 'A')][get_pos(G, 'C')] = 60;G->edges[get_pos(G, 'C')][get_pos(G, 'A')] = 60;G->edges[get_pos(G, 'C')][get_pos(G, 'D')] = 52;G->edges[get_pos(G, 'D')][get_pos(G, 'C')] = 52;G->edges[get_pos(G, 'D')][get_pos(G, 'G')] = 42;G->edges[get_pos(G, 'G')][get_pos(G, 'D')] = 42;G->edges[get_pos(G, 'C')][get_pos(G, 'G')] = 45;G->edges[get_pos(G, 'G')][get_pos(G, 'C')] = 45;G->edges[get_pos(G, 'B')][get_pos(G, 'E')] = 40;G->edges[get_pos(G, 'E')][get_pos(G, 'B')] = 40;G->edges[get_pos(G, 'D')][get_pos(G, 'E')] = 50;G->edges[get_pos(G, 'E')][get_pos(G, 'D')] = 50;G->edges[get_pos(G, 'D')][get_pos(G, 'F')] = 30;G->edges[get_pos(G, 'F')][get_pos(G, 'D')] = 30;G->edges[get_pos(G, 'E')][get_pos(G, 'F')] = 70;G->edges[get_pos(G, 'F')][get_pos(G, 'E')] = 70;PrintGraph(G);PrimMST(G);DestroyGraph(G);return 0;
}

在这里插入图片描述

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

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

相关文章

一周学会Django5 Python Web开发 - Django5内置Admin系统二次开发

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计56条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

System-Verilog 实现DE2-115倒车雷达模拟

System-Verilog 实现DE2-115倒车雷达模拟 引言&#xff1a; 随着科技的不断进步&#xff0c;汽车安全技术也日益成为人们关注的焦点。在众多汽车安全辅助系统中&#xff0c;倒车雷达以其实用性和高效性脱颖而出&#xff0c;成为现代汽车不可或缺的一部分。倒车雷达系统利用超声…

idea中导入代码文件无法修改,显示File is read-only,怎么办?难办?那就别办了------看下面

File is read-only 文件属性只读&#xff0c;不可修改。。。。。 第一次遇到这种问题&#xff0c;去网上搜了一堆方法&#xff0c;都试了&#xff0c;没用&#xff0c;最后居然还建议我重装idea&#xff0c;我还差点信了&#xff0c;经9X9难后&#xff0c;取得真经。 问题解决…

Spring Boot项目中,如何在yml配置文件中读取maven pom.xml文件中的properties标签下的属性值

一、前言 在最近的项目开发过程中&#xff0c;有一个需求&#xff0c;需要在Spring Boot项目的yml配置文件中读取到mave的 pom.xml文件中的properties标签下的属性值&#xff0c;这个要怎么实现呢&#xff1f; 二、技术实践 pom.xml文件中增加测试属性 <properties><…

汇舟问卷:兼职做国外问卷三小时挣200

在繁忙的都市生活中&#xff0c;许多人为了生计而日夜奔波。对于大多数人来说&#xff0c;白天的工作已经足够充实&#xff0c;但依然有很多人选择在下班时间&#xff0c;多做些什么&#xff0c;为自己带来一份额外​的收入。 目前下班做的兼职工作不是跑滴滴&#xff0c;就是…

YOLOV10:参数越少,速度越快,性能更高的新一代目标检测框架

摘要 在过去的几年中&#xff0c;YOLOs由于在计算成本和检测性能之间实现了有效的平衡&#xff0c;已经成为实时目标检测领域的主导范式。研究人员已经探索了YOLOs的架构设计、优化目标、数据增强策略等&#xff0c;取得了显著的进展。然而&#xff0c;对非极大值抑制&#xf…

Redis学习笔记【基础篇】

SQL vs NOSQL SQL&#xff08;Structured Query Language&#xff09;和NoSQL&#xff08;Not Only SQL&#xff09;是两种不同的数据库处理方式&#xff0c;它们在多个维度上有所差异&#xff0c;主要区别包括&#xff1a; 数据结构: SQL&#xff08;关系型数据库&#xff09;…

深入探讨npm、Yarn、pnpm和npx之间的区别

前端生态系统是一个快速发展的领域&#xff0c;充满了各种工具和技术。对于开发人员来说&#xff0c;跟上这些创新可能是一项艰巨的挑战。 在本文中&#xff0c;我们将深入探讨npm、Yarn、pnpm和npx之间的区别&#xff0c;帮助你理解每个工具的不同之处。 包管理器比较 npm …

【一生一芯】

目录 安装Ubuntu 22.04 安装Ubuntu 22.04 我站在巨人的肩膀上&#xff0c;安装教程见VMware安装Ubuntu22.04(英文桌面)教程 备忘一下&#xff1a; 1.Ubuntu中在终端进入root权限但是总提示密码错误的解决方案 对支持 IPv6 的镜像主机执行 ping 操作&#xff1a; 将帐户添加到 …

私有大模型:针对长结构文档的回答方法

作者: Jon Saad-Falcon, Joe Barrow, Alexa Siu, Ani Nenkova, David Seunghyun Yoon, Ryan A. Rossi, Franck Dernoncourt 摘要: 大型语言模型&#xff08;LLMs&#xff09;在处理长文档问答&#xff08;QA&#xff09;时面临着无法适应其小上下文窗口的问题。为了解决这一问…

【计算机视觉】数字图像处理基础知识(模拟和数字图像、采样量化、像素的基本关系、灰度直方图、图像的分类)

一、图像的基本概念 图像(image)&#xff1a;图像这个简单单词其实包含两方面含义&#xff1a; “图”&#xff1a;是指物体反射光or透射光的分布“像”&#xff1a;接收和记录其分布所得到的结果&#xff08;如&#xff1a;人的视觉系统所接收“图”在人脑中形成的映像或认识&…

LLVM入门教学——SanitizerCoverage插桩(Linux)

1、介绍 LLVM 的 SanitizerCoverage 是一种代码覆盖工具&#xff0c;设计用于支持基于 fuzzing 的测试和其他安全相关工具。SanitizerCoverage 在编译时插桩代码&#xff0c;以在运行时收集覆盖信息&#xff0c;从而帮助识别未覆盖的代码路径&#xff0c;提高测试的有效性和全…

算法-随机快排及荷兰国旗优化

文章目录 算法介绍 :1. 随机快排解析2. 荷兰国旗问题3. 随机快排优化4. 总结随机快排 算法介绍 : 随机快速排序和传统的快速排序的逻辑本质是一致的,都是找到一个值作为划分的中间位置,左边数值均小于该数值,右边数值均大于该数值,但是与传统的快排又不一致的是,我们的这个位置…

国内的期权模拟账户怎么申请?

国内的期权模拟账户可以在券商和期权分仓平台处申请开通&#xff0c;期权相比于股票具有杠杆投资、风险控制等新特性。 期权模拟交易客户端能够提供期权的开平仓交易、备兑开仓&#xff0f;平仓、行权等交易指令&#xff0c;下文为大家介绍国内的期权模拟账户怎么申请&#xff…

2024 cicsn Ezheap

文章目录 检查 libc2.35利用adddeleeditshow 思路exp结果 检查 libc2.35 利用 add 0x80个chunk&#xff0c;遍历选一个没有被用的&#xff0c;输入的size<0x501,然后malloc后会清零安装输入的size&#xff0c;然后输入内容&#xff0c;长度也是输入的size dele 指定索引…

第十六课,海龟画图:设置画笔颜色、宽度函数,移动画笔函数

一&#xff0c;turtle.color()&#xff1a;画笔颜色函数 这个函数能设置画笔画出来的颜色&#xff0c;当然&#xff0c;使用它之前你需要认识有哪些“颜料”可供你选择&#xff0c;turtle库的color()函数可以选择以下颜色&#xff1a; "white" 白色&#xff08;建议…

3步轻松月入过万,APP广告新模式大揭秘!

万万没想到&#xff1a;用这个APP广告模式&#xff0c;月入过万竟然如此简单&#xff01; 在移动应用开发的世界里&#xff0c;变现一直是一道难题。 许多APP开发者和产品经理为了提高收益、增强用户黏性&#xff0c;不断尝试各种策略。 然而&#xff0c;很多时候&#xff0c…

2024-6-1 石群电路-20

2024-6-1&#xff0c;星期六&#xff0c;18:24&#xff0c;天气&#xff1a;晴&#xff0c;心情&#xff1a;晴。已经到学校啦&#xff0c;本来打算今天休息一天不更了&#xff0c;但是觉得可以更新完再休息&#xff0c;没有这么累&#xff0c;哈哈哈哈&#xff0c;这就不得不说…

阿里云部署nodejs

目录 1、安装node.js 1-1 进入opt/software 1-2 下载node.js安装包 1-3 解压 2 配置环境变量 2-1 vim中配置环境变量 2-2 命令行中保存环境变量 2-3 检查安装版本 2-3 更换镜像 3、上传node.js项目 1-1 启动项目 1-2 配置对应的安全组 ​编辑 4、pm2启动多个node项…

Linux目录的基本结构(RHEL8系统基本使用之文件操作)

1.Linux的目录树结构 2.各目录的功能介绍 3.理解文件路径表示方法 Who&#xff1f;——>当前登录的用户 Where?——>路径 我要在哪儿创建文件&#xff1f; 我要删除什么地方的什么文件&#xff1f; 我所要查看的文件在哪里&#xff1f; What?——>操作命令 Ho…