当前位置: 首页 > news >正文

C语言-数据结构 弗洛伊德算法(Floyd)邻接矩阵存储

        弗洛伊德算法相比迪杰斯特拉相似的地方都是遍历邻接矩阵不断调整最短路径的信息,并且两种算法面对多源最短路径的时间复杂度都是O(n^3),Floyd采用的是动态规划而Dijkstra是采用贪心的思想。在Floyd中我们将创建两个数组进行辅助,一个path二维数组用于存储路径信息,一个table二维数组用于记录更新各结点间的最短路径长度,table的初始化就是简单的把邻接矩阵的信息复制过来,整个算法都是在这个table表中不断更新,代码中第一层for循环是控制中转结点,另外两行就是遍历整个table二位数组,table[v][k]表示辅助列,table[k][w]表示辅助行,辅助行与辅助列由中转结点控制在整个table表的主对角线上运动,table[v][w]当前扫描的邻接结点信息,如果当前邻接结点的权值大于对应的(辅助行+辅助列的权值和),那么说明找到更短的路径需要进行更新权值,当前邻接结点信息改为(辅助行+辅助列的权值和),同时更新路径信息为中转结点(即前驱顶点),代码中path[v][k]存储了对应的中转结点信息,利用它更新当前邻接结点的前驱结点(对应的中转结点)信息,当循环结束整个图各顶点到达其他所有顶点的最短距离就计算完成了,最后我们打印table矩阵的上三角部分因为两个结点的表示可以用一个方向就行,例如A->F打印了就可以表示F->A,并不需求遍历完全部table矩阵信息,同时打印路径信息的第二个for循环有个+1操作是为了避免打印AA、BB这种自己到自己的路径,也就是不打印主对角线,path路径信息的存储也同样用到并查集的部分思想在上一篇博文提过,在代码中通过不断循环path路径能够找到它的前驱结点一步步把所有路径结点信息找到,相比迪杰斯特拉倒着找结点信息,这里我们可以之间通过path二维数组顺序查找到路径信息,也是非常巧妙的!

 我们将创建下面的无向权值图:

84ef03cba4ba478383b338ae5884012a.png

  邻接矩阵的绘制还是手动赋值上三角,并通过矩阵对称性生成整个邻接矩阵,其中最小生成树中需要用到权值,对应原本有边的地方之前我是用1表示,现在改成边对应的权值,之前的0表示没有边,现在改成99表示为无穷,其实应该换成更大的值以确保树的边权值都小于这个最大值,但为了方便对齐显示看邻接矩阵,就使用了比本图中各边长较大的99来表示最大值。

9eefaa5c866742cbb239f5f9de2aff7d.png

Floyd算法代码:

//存储所有顶点的路径信息
typedef int Patharc[MAXVEX][MAXVEX];
//最短路径表copy邻接矩阵,不断扫描更新各顶点相互间的最短距离
typedef int ShortestPathTable[MAXVEX][MAXVEX];
// Floyd算法实现
void Floyd(MGraph G, Patharc path, ShortestPathTable table) {int v, w, k;// 初始化表和路径矩阵for (v = 0; v < G.numNodes; v++) {for (w = 0; w < G.numNodes; w++) {table[v][w] = G.arc[v][w];  // 初始化最短路径表if (G.arc[v][w] < INFINITY) {path[v][w] = w;  // 有直接边时,路径是目标顶点}else {path[v][w] = -1; // 如果没有边,则设为 -1}}}// Floyd算法的核心计算for (k = 0; k < G.numNodes; k++) {  // 遍历每个顶点作为中间顶点for (v = 0; v < G.numNodes; v++) {  // 遍历起点for (w = 0; w < G.numNodes; w++) {  // 遍历终点// 如果通过顶点 k 的路径更短,则更新路径和最短路径表if (table[v][w] > table[v][k] + table[k][w]) {table[v][w] = table[v][k] + table[k][w];path[v][w] = path[v][k];}}}}// 打印各顶点间的最短路径printf("各顶点间最短路径如下:\n");for (v = 0; v < G.numNodes; v++) {for (w = v + 1; w < G.numNodes; w++) {  // 遍历每对顶点//Array数组存储顶点ABCDEFGHprintf("%c-%c weight:%d\n", Array[v], Array[w], table[v][w]);k = path[v][w];  // 从起点到终点的路径printf("path:%d", v);while (k != w) {  // 路径输出printf("->%d", k);k = path[k][w];}printf("->%d\n", w);}printf("\n");}
}

完整代码(包括邻接矩阵的创建、Floyd算法)

#include "stdio.h"    
#include "stdlib.h"   
#include "math.h"  
#include "time.h"// 禁用特定的警告
#pragma warning(disable:4996)// 定义一些常量和数据类型
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXVEX 8 /* 最大顶点数,用户定义 */
#define MAXEDGE 10 /* 最大边数,用户定义 */
#define GRAPH_INFINITY 99 /* 用0表示∞,表示不存在边 *//* 定义状态、顶点和边的类型 */
typedef int Status;  /* Status是函数的返回类型,如OK表示成功 */
typedef char VertexType; /* 顶点的类型,用字符表示 */
typedef int EdgeType; /* 边上的权值类型,用整数表示 */
typedef int Boolean; /* 布尔类型 */
// 定义顶点标签
char Array[] = "ABCDEFGHI";/* 图的邻接矩阵结构体 */
typedef struct
{VertexType vexs[MAXVEX]; /* 顶点表 */EdgeType arc[MAXVEX][MAXVEX]; /* 邻接矩阵,表示边的权值 */int numNodes, numEdges; /* 图中当前的顶点数和边数 */
} MGraph;//存储所有顶点的路径信息
typedef int Patharc[MAXVEX][MAXVEX];
//最短路径表copy邻接矩阵,不断扫描更新各顶点相互间的最短距离
typedef int ShortestPathTable[MAXVEX][MAXVEX];/* 创建一个无向网图的邻接矩阵表示 */
void CreateMGraph(MGraph* G)
{int i, j, k, w;// 初始化图的顶点数和边数G->numNodes = 8;G->numEdges = 10;// 初始化邻接矩阵和顶点表for (i = 0; i < G->numNodes; i++) {for (j = 0; j < G->numNodes; j++) {G->arc[i][j] = GRAPH_INFINITY; /* 初始化邻接矩阵为∞ */}G->vexs[i] = Array[i]; /* 初始化顶点表 */}G->arc[0][0] = GRAPH_INFINITY;G->arc[0][1] = 10;G->arc[0][2] = GRAPH_INFINITY;G->arc[0][3] = GRAPH_INFINITY;G->arc[0][4] = GRAPH_INFINITY;G->arc[0][5] = 11;G->arc[0][6] = GRAPH_INFINITY;G->arc[0][7] = GRAPH_INFINITY;G->arc[1][0] = GRAPH_INFINITY;G->arc[1][1] = GRAPH_INFINITY;G->arc[1][2] = 23;G->arc[1][3] = GRAPH_INFINITY;G->arc[1][4] = GRAPH_INFINITY;G->arc[1][5] = GRAPH_INFINITY;G->arc[1][6] = 12;G->arc[1][7] = GRAPH_INFINITY;G->arc[2][0] = GRAPH_INFINITY;G->arc[2][1] = GRAPH_INFINITY;G->arc[2][2] = GRAPH_INFINITY;G->arc[2][3] = 21;G->arc[2][4] = GRAPH_INFINITY;G->arc[2][5] = GRAPH_INFINITY;G->arc[2][6] = GRAPH_INFINITY;G->arc[2][7] = GRAPH_INFINITY;G->arc[3][0] = GRAPH_INFINITY;G->arc[3][1] = GRAPH_INFINITY;G->arc[3][2] = GRAPH_INFINITY;G->arc[3][3] = GRAPH_INFINITY;G->arc[3][4] = GRAPH_INFINITY;G->arc[3][5] = GRAPH_INFINITY;G->arc[3][6] = GRAPH_INFINITY;G->arc[3][7] = 11;G->arc[4][0] = GRAPH_INFINITY;G->arc[4][1] = GRAPH_INFINITY;G->arc[4][2] = GRAPH_INFINITY;G->arc[4][3] = GRAPH_INFINITY;G->arc[4][4] = GRAPH_INFINITY;G->arc[4][5] = 47;G->arc[4][6] = GRAPH_INFINITY;G->arc[4][7] = 80;G->arc[5][0] = GRAPH_INFINITY;G->arc[5][1] = GRAPH_INFINITY;G->arc[5][2] = GRAPH_INFINITY;G->arc[5][3] = GRAPH_INFINITY;G->arc[5][4] = GRAPH_INFINITY;G->arc[5][5] = GRAPH_INFINITY;G->arc[5][6] = 6;G->arc[5][7] = GRAPH_INFINITY;G->arc[6][0] = GRAPH_INFINITY;G->arc[6][1] = GRAPH_INFINITY;G->arc[6][2] = GRAPH_INFINITY;G->arc[6][3] = GRAPH_INFINITY;G->arc[6][4] = GRAPH_INFINITY;G->arc[6][5] = GRAPH_INFINITY;G->arc[6][6] = GRAPH_INFINITY;G->arc[6][7] = 8;G->arc[7][0] = GRAPH_INFINITY;G->arc[7][1] = GRAPH_INFINITY;G->arc[7][2] = GRAPH_INFINITY;G->arc[7][3] = GRAPH_INFINITY;G->arc[7][4] = GRAPH_INFINITY;G->arc[7][5] = GRAPH_INFINITY;G->arc[7][6] = GRAPH_INFINITY;G->arc[7][7] = GRAPH_INFINITY;// 由于是无向图,邻接矩阵是对称的,需要将其对称for (int i = 0; i < G->numNodes; i++) {for (int j = 0; j < G->numNodes; j++) {G->arc[j][i] = G->arc[i][j];}}// 打印邻接矩阵printf("邻接矩阵为:\n");printf("     ");for (int i = 0; i < G->numNodes; i++) {printf("%2d ", i); /* 打印列索引 */}printf("\n     ");for (int i = 0; i < G->numNodes; i++) {printf("%2c ", G->vexs[i]); /* 打印顶点标签 */}printf("\n");for (int i = 0; i < G->numNodes; i++) {printf("%2d", i); /* 打印行索引 */printf("%2c ", G->vexs[i]); /* 打印顶点标签 */for (int j = 0; j < G->numNodes; j++) {if (G->arc[i][j] != 99) {printf("\033[31m%02d \033[0m", G->arc[i][j]); /* 打印邻接矩阵中的权值 */}else {printf("%02d ", G->arc[i][j]); /* 打印邻接矩阵中的权值 */}}printf("\n");}
}// Floyd算法实现
void Floyd(MGraph G, Patharc path, ShortestPathTable table) {int v, w, k;// 初始化表和路径矩阵for (v = 0; v < G.numNodes; v++) {for (w = 0; w < G.numNodes; w++) {table[v][w] = G.arc[v][w];  // 初始化最短路径表if (G.arc[v][w] < INFINITY) {path[v][w] = w;  // 有直接边时,路径是目标顶点}else {path[v][w] = -1; // 如果没有边,则设为 -1}}}// Floyd算法的核心计算for (k = 0; k < G.numNodes; k++) {  // 遍历每个顶点作为中间顶点for (v = 0; v < G.numNodes; v++) {  // 遍历起点for (w = 0; w < G.numNodes; w++) {  // 遍历终点// 如果通过顶点 k 的路径更短,则更新路径和最短路径表if (table[v][w] > table[v][k] + table[k][w]) {table[v][w] = table[v][k] + table[k][w];path[v][w] = path[v][k];}}}}// 打印各顶点间的最短路径printf("\n各顶点间最短路径如下:\n");for (v = 0; v < G.numNodes; v++) {for (w = v + 1; w < G.numNodes; w++) {  // 遍历每对顶点//Array数组存储顶点ABCDEFGHprintf("%c-%c weight:%d\n", Array[v], Array[w], table[v][w]);k = path[v][w];  // 从起点到终点的路径printf("path:%d", v);while (k != w) {  // 路径输出printf("->%d", k);k = path[k][w];}printf("->%d\n", w);}printf("\n");}
}// 主函数
int main(void) {MGraph G;/* 创建图 */CreateMGraph(&G);  // 创建并初始化图 GPatharc path;ShortestPathTable table;Floyd(G, path, table);  // 计算最短路径return 0;
}

 无向权值图:

84ef03cba4ba478383b338ae5884012a.png

运行结果:

相关文章:

C语言-数据结构 弗洛伊德算法(Floyd)邻接矩阵存储

弗洛伊德算法相比迪杰斯特拉相似的地方都是遍历邻接矩阵不断调整最短路径的信息&#xff0c;并且两种算法面对多源最短路径的时间复杂度都是O(n^3)&#xff0c;Floyd采用的是动态规划而Dijkstra是采用贪心的思想。在Floyd中我们将创建两个数组进行辅助&#xff0c;一个path二维…...

pyspark 安装记录

1、安装软件 1、python 3.10 2、hadoop-3.3.4 里面的winutils 要记得添加 3、java-17 4、spark-3.5.1-bin-hadoop3 python 安装 pyspark,Jupyter notebook pip install pyspark pip install jupyter notebook 2、添加环境变量 JAVA_HOME=C:\PySparkService\java-17H…...

高度可定制的电竞鼠标,雷柏VT1 PRO MAX体验

不管是菜鸟还是老鸟&#xff0c;游戏玩到某个阶段很容易出现瓶颈&#xff0c;在游戏的某个阶段&#xff0c;这里面制约最大的除了操作之外&#xff0c;实际上还是我们用的硬件。比如在PC游戏中&#xff0c;鼠标的影响就非常大&#xff0c;像是在游戏中如果鼠标延迟过高&#xf…...

经验笔记:SOA(面向服务的架构)

SOA&#xff08;面向服务的架构&#xff09;经验笔记 引言 SOA&#xff08;Service-Oriented Architecture, 面向服务的架构&#xff09;是一种设计原则&#xff0c;用于构建灵活且可扩展的分布式系统。SOA强调将应用程序的不同功能封装为独立的服务&#xff0c;这些服务通过…...

triton之ttir学习

一 基本语句 1 常量 %cst arith.constant dense<520192> : tensor<4096xi32> %c127_i32 arith.constant 127 : i32 %cst arith.constant dense<520192> : tensor<4096xi32> 解释&#xff1a;这条语句定义了一个名为 %cst 的常量&#xff0c;它…...

如何在AWS账户上进行充值:一份详尽指南

大家好&#xff0c;小编今天给大家带来一份关于如何在AWS账户上进行充值的详尽指南。对于使用AWS服务的用户来说&#xff0c;保持账户余额充足是确保服务不中断的关键。下面&#xff0c;九河云将详细讲解具体的操作步骤。 步骤一&#xff1a;登录AWS管理控制台 首先&#xff…...

(六十四)第 10 章 内部排序(静态链表的插入排序)

示例代码 staticLinkList.h // 静态链表的插入排序实现头文件#ifndef STATIC_LINK_LIST_H #define STATIC_LINK_LIST_H#include "errorRecord.h"#define SIZE 100 #define NUM 8typedef int InfoType; typedef int KeyType;typedef struct {KeyType key;InfoType inf…...

appium历史版本地址链接

appium / Appium.app / Downloads — Bitbucket ios的appium界面图 链接: https://pan.baidu.com/s/1i8BRaZgQA3ImLUhKZjfhiA 提取码: 5c8b...

TCPIP网络编程(尹圣雨)UDP 轮流收发消息(windows)

端口号写的是 2345 客户端 #include <iostream> #include <winsock2.h> #pragma comment(lib, "ws2_32.lib")using std::cout; using std::endl; using std::cin;int main() {WSADATA wsa;if (WSAStartup(MAKEWORD(2, 2), &wsa) ! 0){cout <<…...

【相机方案(2)】V4L2 支持相机图像直接进入GPU内存吗?DeepStream 确实可以将图像数据高效地放入GPU内存进行处理!

V4L2 支持相机图像直接进入GPU内存吗&#xff1f; V4L2&#xff08;Video4Linux Two&#xff09;是Linux内核中用于视频捕获和播放的API&#xff0c;它本身并不直接支持将相机捕获的图像数据直接拷贝到GPU内存而不经过CPU内存。V4L2主要关注于视频设备的控制、数据的捕获和播放…...

UEFI——PEI阶段

一、PEI介绍 Pre-EFI Initialization&#xff08;PEI&#xff09;在引导的早期被调用&#xff0c;仅利用CPU资源调用PEIM&#xff0c;这些PEIM负责&#xff1a; &#xff08;1&#xff09;初始化一些永久内存 &#xff08;2&#xff09;在HOBs中描述内存信息 &#xff08;3…...

Nacos下载和启动

Nacos是什么&#xff1f; 一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台 下载 https://github.com/alibaba/nacos/releases/tag/2.1.1启动 将下载好的Nacos解压缩&#xff0c;然后到bin目录下打开cmd 输入指令&#xff1a;startup.cmd -m standalone 出…...

怎么选择适合的服务器

大家都知道&#xff0c;不管是公司还是个人&#xff0c;在数字化浪潮已经席卷全球的环境下&#xff0c;大家对服务器的需求是日渐增长的。很多人在买服务器的时候&#xff0c;多少都有点选择困难&#xff0c;今天我们就来对比下物理服务器和弹性云服务器&#xff0c;看看选哪个…...

通义千问大模型Java调用,百炼

文章目录 一、大模型服务平台[百炼](https://help.aliyun.com/zh/model-studio/getting-started)二、Java sdk调用与eventStream三、百炼平台其它 一、大模型服务平台百炼 百炼是阿里新出的一个大模型服务平台&#xff0c;聚合了多个千问大模型及其它一些大模型的调用&#xf…...

新发现!一键管理所有远程会话的神器——1Remote

大家好&#xff0c;今天给大家介绍一款非常实用的工具——1Remote&#xff0c;这是一款现代化的个人远程会话管理器与启动器&#xff0c;让您的远程工作变得更加轻松高效&#xff01; 项目介绍 &#x1f680; 核心功能概览 多协议支持&#xff1a;1Remote支持RDP、SSH、VNC、…...

华为 HCIP 认证费用和报名资格

在当今竞争激烈的信息技术领域&#xff0c;华为 HCIP认证备受关注。它不仅能提升个人的技术实力与职业竞争力&#xff0c;也为企业选拔优秀人才提供了重要依据。以下将详细介绍华为 HCIP 认证的费用和报名资格。 一、HCIP 认证费用 华为HCIP认证的费用主要由考试费和培训费构成…...

Linux下载压缩包:tar.gz、zip、tar.bz2格式全攻略

在 Linux 中&#xff0c;下载各种格式的压缩包&#xff08;如 .tar.gz、.zip、.tar.bz2 等&#xff09;通常使用命令行工具如 wget 和 curl。 1. 使用 wget 下载压缩包 wget 是 Linux 中最常用的文件下载工具&#xff0c;支持 HTTP、HTTPS、FTP 等协议&#xff0c;可以直接从…...

运行PaddleOCR报错:requests.exceptions.SSLError: HTTPSconnectionPool……

文章目录 问题描述解决方法 问题描述 在运行以下代码时报错&#xff1a; ocr PaddleOCR(lang"en")解决方法 打开cmd&#xff0c;输入以下命令&#xff0c;查找Python解释器所在路径。 找到 Lib\site-packages\paddleocr\ppocr\utils\network.py&#xff0c;将代码…...

基于STM32L431小熊派设计的智能花盆(微信小程序+腾讯云IOT)(223)

文章目录 一、前言1.1 项目介绍【1】项目背景【2】设计实现的功能【3】项目硬件模块组成1.2 设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3 项目开发背景【1】选题的意义【2】可行性分析【3】参考文献1.4 开发工具的选择【1】设备端开发【2】上位机开发1.5 系统框架图…...

CentOS 入门必备基础知识

CentOS&#xff08;Community ENTerprise Operating System&#xff09;是一个基于Red Hat Enterprise Linux&#xff08;RHEL&#xff09;的免费开源操作系统&#xff0c;广泛用于服务器环境。它以其稳定性、安全性和社区支持而闻名&#xff0c;对于初学者来说掌握一些基础知识…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...