数据结构 | 图的最短路径 Floyd算法

news2024/11/24 6:52:43

一、数据结构定义

typedef int VertexType;
typedef int EdgeType;

/*图*/
typedef struct {
    VertexType Vexs[SIZE];		//结点 
    EdgeType Edges[SIZE][SIZE];	//权值 
    int vexnum, arcnum;
}MGraph;

/*路径*/
typedef struct {
    int path[SIZE][SIZE];
    EdgeType length;
}Path;

1.二维数组 Edges[SIZE][SIZE] 储存图的边权数据,一维数组 Vexs[SIZE] 储存图的结点数据;

2.结构体 Path 保存计算后的路径信息。

二、算法详解

/* 初始化图并输入权值 */
MGraph* InitGraph() {
    MGraph* G = (MGraph*)malloc(sizeof(MGraph));
    G->vexnum = 4;
    G->arcnum = 8;
    //初始化图的邻接矩阵 Edges[SIZE][SIZE]
    for (int i = 0; i < G->vexnum; i++) {
        for (int j = 0; j < G->vexnum; j++) {
            if (i == j)	G->Edges[i][j] = 0;		//对角线权值为0 
            else		G->Edges[i][j] = MaxNum;	//除对角线外所有权值为无穷大 
        }
    }
    //初始化图的结点矩阵 Vexs[SIZE]
    VertexType v[4] = { 0,1,2,3 };
    for (int i = 0; i < G->vexnum; i++)
        G->Vexs[i] = v[i];
    //初始化图的边权
    int  start_vex[8] = { 0,0,1,1,2,2,2,3 };
    int    end_vex[8] = { 1,3,2,3,0,1,3,2 };
    int vex_weight[8] = { 5,7,4,2,3,3,2,1 };
    for (int i = 0; i < G->arcnum; i++)
        G->Edges[start_vex[i]][end_vex[i]] = vex_weight[i];
    return G;
}

/* 初始化路径矩阵 */
Path InitPath() {
    Path path;
    path.length = 0;
    return path;
}

/* Floyd算法寻找最短路径 */
void Floyd(MGraph* Graph, Path *path) {
    int i, j, k, nun = Graph->vexnum;
    int temp[SIZE][SIZE];
    // 初始化
    for (i = 0; i < nun; i++) {
        for (j = 0; j < nun; j++) {
            temp[i][j] = Graph->Edges[i][j];
            path->path[i][j] = -1;
        }
    }
    // 算法主体
    for (k = 0; k < nun; k++) {
        for (i = 0; i < nun; i++) {
            for (j = 0; j < nun; j++) {
                if (temp[i][j] > temp[i][k] + temp[k][j]) {
                    temp[i][j] = temp[i][k] + temp[k][j];
                    path->path[i][j] = k;
                }
            }
        }
    }
}

三、运行结果

        main方法代码如下:

int main() {
    MGraph* Graph = InitGraph();
    Path path = InitPath();

    Floyd(Graph, &path);
    PrintPath(Graph, &path);
    return 0;
}

 

四、源代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#define SIZE 4          //邻接矩阵大小(v0 - v3)
#define MaxNum 999      //不可到达点的权值(即无穷大)

typedef int VertexType;
typedef int EdgeType;

/*图*/
typedef struct {
    VertexType Vexs[SIZE];		//结点 
    EdgeType Edges[SIZE][SIZE];	//权值 
    int vexnum, arcnum;
}MGraph;

/*路径*/
typedef struct {
    int path[SIZE][SIZE];
    EdgeType length;
}Path;


/* 初始化图并输入权值 */
MGraph* InitGraph() {
    MGraph* G = (MGraph*)malloc(sizeof(MGraph));
    G->vexnum = 4;
    G->arcnum = 8;
    //初始化图的邻接矩阵 Edges[SIZE][SIZE]
    for (int i = 0; i < G->vexnum; i++) {
        for (int j = 0; j < G->vexnum; j++) {
            if (i == j)	G->Edges[i][j] = 0;		//对角线权值为0 
            else		G->Edges[i][j] = MaxNum;	//除对角线外所有权值为无穷大 
        }
    }
    //初始化图的结点矩阵 Vexs[SIZE]
    VertexType v[4] = { 0,1,2,3 };
    for (int i = 0; i < G->vexnum; i++)
        G->Vexs[i] = v[i];
    //初始化图的边权
    int  start_vex[8] = { 0,0,1,1,2,2,2,3 };
    int    end_vex[8] = { 1,3,2,3,0,1,3,2 };
    int vex_weight[8] = { 5,7,4,2,3,3,2,1 };
    for (int i = 0; i < G->arcnum; i++)
        G->Edges[start_vex[i]][end_vex[i]] = vex_weight[i];
    return G;
}

/* 初始化路径矩阵 */
Path InitPath() {
    Path path;
    path.length = 0;
    return path;
}

/* Floyd算法寻找最短路径 */
void Floyd(MGraph* Graph, Path *path) {
    int i, j, k, nun = Graph->vexnum;
    int temp[SIZE][SIZE];
    // 初始化
    for (i = 0; i < nun; i++) {
        for (j = 0; j < nun; j++) {
            temp[i][j] = Graph->Edges[i][j];
            path->path[i][j] = -1;
        }
    }
    // 算法主体
    for (k = 0; k < nun; k++) {
        for (i = 0; i < nun; i++) {
            for (j = 0; j < nun; j++) {
                if (temp[i][j] > temp[i][k] + temp[k][j]) {
                    temp[i][j] = temp[i][k] + temp[k][j];
                    path->path[i][j] = k;
                }
            }
        }
    }
}

/* 递归寻找最短路径 */
void FindPath(int start, int end, Path* path, MGraph* Graph) {
    if (path->path[start][end] == -1) {
        printf("-> %d ", end);
        path->length = path->length + Graph->Edges[start][end];
    }
    else {
        int mid = path->path[start][end];
        FindPath(start, mid, path, Graph);
        FindPath(mid, end, path, Graph);
    }
}

/* 打印最短路径 */
void PrintPath(MGraph* Graph, Path* path) {
    VertexType start, end;
    printf("输入起点:");
    scanf("%d", &start);
    printf("输入终点:");
    scanf("%d", &end);

    printf("%d ", start);
    FindPath(start, end, path, Graph);
    printf("= %d", path->length);
}

int main() {
    MGraph* Graph = InitGraph();
    Path path = InitPath();

    Floyd(Graph, &path);
    PrintPath(Graph, &path);
    return 0;
}

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

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

相关文章

给父组件添加点击事件,点击时获取父组件的target

我想获取class为 mes-it 的dom元素结果每次拿到的 target都是子元素 查了查资料可以用 pointer-events: none; 来规避子元素成为target 就是上面图片style 里面的样式

【图灵奖得主Frederick P.Brooks, Jr.带你走进软件工程的世界——《人月神话》】

畅销业界48年的传奇经典 被引频次最高的软工神话 本书为复杂项目管理提供了极具洞察力的见解、发人深省的观点以及大量的软件工程实践。 直至今天&#xff0c;《人月神话》依然活跃在软件开发各个领域的话题中&#xff01; 我是一个书狂&#xff0c;积习甚深&#xff0c;费尽心…

Python自动化测试五大框架(测试员收藏夹必备)

自2018年被评选为编程语言以来&#xff0c;Python在各大排行榜上一直都是名列前茅。目前&#xff0c;它在Tiobe指数中排名第三个&#xff0c;仅次于Java和C。随着该编程语言的广泛使用&#xff0c;基于Python的自动化测试框架也应运而生&#xff0c;且不断发展与丰富。 因此&am…

PyQt5调用Window弹窗,选择文件、选择多个文件、选择文件夹、保存文件

前言 本篇在讲什么 PyQt5调取windows选择和导出弹窗 本篇适合什么 适合初学Python的小白 适合使用pyqt5的开发项目 本篇需要什么 对Python语法有简单认知 依赖Python3.7环境 依赖Pycharm编辑器 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xf…

01. 找到数组的中间位置 ——【Leetcode每日一题】

1991. 找到数组的中间位置 难度&#xff1a;简单 给你一个下标从 0 开始的整数数组 nums &#xff0c;请你找到 最左边 的中间位置 middleIndex &#xff08;也就是所有可能中间位置下标最小的一个&#xff09;。 中间位置 middleIndex 是满足 nums[0] nums[1] … nums[m…

【dc-dc】降压恒压电源管理IC 平衡车控制器 电动车控制器 以太网交换机驱动芯片

产品 AP8851 一款宽电压范围降压型DC-DC 电源管理芯片&#xff0c;内部集成使能开关控制、基准电源、误差放大器、过热保护、限流保护、短路保护等功能&#xff0c;非常适合在宽输入电压范围具有优良的负载和线性调整度。AP8851 芯片包含每周期的峰值限流、软启动、过压保护和…

【计算机视觉 | 目标检测】术语理解9:AIGC的理解,对比学习,解码器,Mask解码器,耦合蒸馏,半耦合,图像编码器和组合解码器的耦合优化

文章目录 一、AIGC的理解二、对比学习三、解码器四、Mask解码器五、耦合蒸馏六、半耦合七、图像编码器和组合解码器的耦合优化 一、AIGC的理解 AIGC指的是使用人工智能技术自动生成的各类数字内容,包括文本、图像、音频、视频等。它利用机器学习模型进行智能化内容生成。 主要…

Oracle快速将A库的数据库对象同步到B库(包括数据)

1.在pl/sql中导出A的用户对象 2.导出表数据&#xff0c;直接导PDE文件 如果PDE不行的话就到选择第一个dmp 3.然后把用户B的对象重新创建一遍&#xff0c;数据导进去。 创建对象的时候table和sequence都要删掉重新创建&#xff0c;不然会报已存在。

你会合并数组吗?采用数组大小顺序排列合并C语言实现

第一个代码块进行的是两个数组进行合并&#xff0c;然后顺序排列出来定义两个数组里面各有几个元素然后采用循环输入相应的数字&#xff0c;这里注意是要在每一个数组中顺序排列的&#xff0c;也就是从大到小输入之后采用循环进行比较比较完跳出循环后因为两个数组中元素个数不…

【安装】安装MySQL 相关配置 Navicat 的使用入门 SQL语句初步

目录 安装MySQL选择custom选择MySQL Server选择服务安装路径和数据存储路径 配置MySQL配置端口号选择授权方式设置root用户的密码 Navicat建立连接新建数据库新建表添加字段设置主键 SQL语句DML&#xff08;重点&#xff09;DQL&#xff08;重点&#xff09;运算符其它函数增删…

视频去除水印怎么做?四个方法分享给你!

水印是在许多视频中常见的一种保护措施&#xff0c;但有时它有可能会妨碍我们对视频内容的欣赏。如果你想去除视频中的水印&#xff0c;下面将介绍四种简单有效的方法&#xff0c;让你轻松解决这个问题。 方法一&#xff1a;使用记灵在线工具 记灵在线工具是一款强大的在线视…

Shell通配符和正则表达式

目录 ​​​​​​​grep 通配符 正则表达式 grep grep家族有三大成员分别为&#xff1a; grep&#xff1a;支持使用基本正则表达式。 egrep&#xff1a;支持使用扩展正则表达式。 fgrep&#xff1a;不支持使用正则表达式&#xff0c;即所有的正则表达式中的元字符都将作…

mt管理器使用(app管理)

http://www.360doc.com/content/12/0121/07/13646414_997668971.shtml

常用的访问控制权限模型DAC RBAC

常用的访问控制权限模型DAC RBAC 文章目录 常用的访问控制权限模型DAC RBACLinux 自主访问控制与强制访问控制术语概念存取访问控制 Access Control自主访问控制强制访问控制 基于角色的权限控制模型RBAC模型管理方法RBAC0的管理命令RBAC0的系统支持方法RBAC0的高级审查持方法 …

❤️创意网页:经典透明登录页面(好看易学易用)

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

thinkphp模型递归查询

效果图&#xff1a; 查询代码&#xff1a; use app\model\Menu;function getMenuList(string $uid) {$list Menu::where(pid, $uid)->select();foreach ($list as $val) {$val[children] getMenuList($val->uid);}return $list; }function getMenuBelong(string $uid)…

springboot人事管理系统

本项目在开发和设计过程中涉及到原理和技术有: B/S、java技术和MySQL数据库等等&#xff1b;将按以下章节进行开发设计&#xff1b; 绪论&#xff1b;剖析项目背景,说明研究的内容。 开发技术&#xff1b;系统主要使用了java技术&#xff0c;b/s模式和myspl数据库&#xff0c;并…

如何操作MySQL数据库数据

目录 一、MySQL数据库概念 数据 表&#xff08;数据表&#xff09; 数据库 数据库管理系统 数据库的建立和维护功能 数据定义功能 数据操纵功能 数据库的运行管理功能 通信功能 数据流向 二、主流数据库分类 1.SQL Server 数据库 &#xff08;微软分公司产品&…

【力扣算法11】之 8. 字符串转换整数 (atoi) python

文章目录 问题描述示例1示例2示例3提示 思路分析代码分析完整代码详细分析运行效果截图调用示例运行结果 完结 问题描述 请你来实现一个 myAtoi(string s) 函数&#xff0c;使其能将字符串转换成一个 32 位有符号整数&#xff08;类似 C/C 中的 atoi 函数&#xff09;。 函数 m…

基于scrcpy的Android群控项目重构,集成Appium服务执行自动化测试用例

系列文章目录 基于scrcpy的Android群控项目重构 基于scrcpy的Android群控项目重构 进阶版 基于scrcpy的Android群控项目重构&#xff0c;获取Android屏幕元素信息并编写自动化事件&#xff08;视频&#xff09; 基于scrcpy的Android群控项目重构&#xff0c;获取Android屏幕…