本章介绍弗洛伊德算法。和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现。后续再分别给出C++和Java版本的实现。

弗洛伊德算法介绍

和Dijkstra算法一样,弗洛伊德(Floyd)算法也是一种用于寻找给定的加权图中顶点间最短路径的算法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。

基本思想

通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

假设图G中顶点个数为N,则需要对矩阵S进行N次更新。初始时,矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。 接下来开始,对矩阵S进行N次更新。第1次更新时,如果"a[i][j]的距离" > "a[i][0]+a[0][j]"(a[i][0]+a[0][j]表示"i与j之间经过第1个顶点的距离"),则更新a[i][j]为"a[i][0]+a[0][j]"。 同理,第k次更新时,如果"a[i][j]的距离" > "a[i][k]+a[k][j]",则更新a[i][j]为"a[i][k]+a[k][j]"。更新N次之后,操作完成!

单纯的看上面的理论可能比较难以理解,下面通过实例来对该算法进行说明。

弗洛伊德算法图解

以上图G4为例,来对弗洛伊德进行算法演示。

初始状态:S是记录各个顶点间最短路径的矩阵。

第1步:初始化S。

矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。实际上,就是将图的原始矩阵复制到S中。

注:a[i][j]表示矩阵S中顶点i(第i个顶点)到顶点j(第j个顶点)的距离。

第2步:以顶点A(第1个顶点)为中介点,若a[i][j] > a[i][0]+a[0][j],则设置a[i][j]=a[i][0]+a[0][j]。

以顶点a[1]6,上一步操作之后,a[1][6]=∞;而将A作为中介点时,(B,A)=12,(A,G)=14,因此B和G之间的距离可以更新为26。

同理,依次将顶点B,C,D,E,F,G作为中介点,并更新a[i][j]的大小。

弗洛伊德算法的代码说明

以"邻接矩阵"为例对弗洛伊德算法进行说明,对于"邻接表"实现的图在后面会给出相应的源码。

1. 基本定义

// 邻接矩阵

typedef struct _graph

{

char vexs[MAX]; // 顶点集合

int vexnum; // 顶点数

int edgnum; // 边数

int matrix[MAX][MAX]; // 邻接矩阵

}Graph, *PGraph;

Graph是邻接矩阵对应的结构体。

vexs用于保存顶点,vexnum是顶点数,edgnum是边数;matrix则是用于保存矩阵信息的二维数组。例如,matrix[i][j]=1,则表示"顶点i(即vexs[i])"和"顶点j(即vexs[j])"是邻接点;matrix[i][j]=0,则表示它们不是邻接点。

2. 弗洛伊德算法

/*

* floyd最短路径。

* 即,统计图中各个顶点间的最短路径。

*

* 参数说明:

* G -- 图

* path -- 路径。path[i][j]=k表示,"顶点i"到"顶点j"的最短路径会经过顶点k。

* dist -- 长度数组。即,dist[i][j]=sum表示,"顶点i"到"顶点j"的最短路径的长度是sum。

*/

void floyd(Graph G, int path[][MAX], int dist[][MAX])

{

int i,j,k;

int tmp;

// 初始化

for (i = 0; i < G.vexnum; i++)

{

for (j = 0; j < G.vexnum; j++)

{

dist[i][j] = G.matrix[i][j]; // "顶点i"到"顶点j"的路径长度为"i到j的权值"。

path[i][j] = j; // "顶点i"到"顶点j"的最短路径是经过顶点j。

}

}

// 计算最短路径

for (k = 0; k < G.vexnum; k++)

{

for (i = 0; i < G.vexnum; i++)

{

for (j = 0; j < G.vexnum; j++)

{

// 如果经过下标为k顶点路径比原两点间路径更短,则更新dist[i][j]和path[i][j]

tmp = (dist[i][k]==INF || dist[k][j]==INF) ? INF : (dist[i][k] + dist[k][j]);

if (dist[i][j] > tmp)

{

// "i到j最短路径"对应的值设,为更小的一个(即经过k)

dist[i][j] = tmp;

// "i到j最短路径"对应的路径,经过k

path[i][j] = path[i][k];

}

}

}

}

// 打印floyd最短路径的结果

printf("floyd: \n");

for (i = 0; i < G.vexnum; i++)

{

for (j = 0; j < G.vexnum; j++)

printf("%2d ", dist[i][j]);

printf("\n");

}

}

弗洛伊德算法的源码

这里分别给出"邻接矩阵图"和"邻接表图"的弗洛伊德算法源码。

java 二维数组 floyd_Floyd算法(一)之 C语言详解相关推荐

  1. java二维数组存储数据,从键盘上录入学生人数,考试科目数,以及每个学生每科分数,输出每个学生的最高分、最低分、总分、平均分

    java二维数组存储数据,从键盘上录入学生人数,考试科目数,以及每个学生每科分数,输出每个学生的最高分.最低分.总分.平均分 import java.util.Scanner;/* * 二维数组存储数 ...

  2. java二维数组的遍历

    java二维数组的遍历 /* * java二维数组的遍历 * 二维数组,数组座位数组元素类型的数组,数组的数组 * */ public class Test14 {public static void ...

  3. 案例演示Python二维列表与Java二维数组

    1.Python二维列表案例演示 运行程序,结果如下: 2.案例演示Java二维数组 package net.hw.test;/*** 功能:二维数组用法示例* 作者:华卫* 日期:2013年12月1 ...

  4. python:实现9×9二维数组数独算法(附完整源码)

    python:实现9×9二维数组数独算法 from __future__ import annotationsMatrix = list[list[int]]# assigning initial v ...

  5. java二维数组遍历与元素查找

    java二维数组 格式 数据类型 [ ][ ] arrayName = new 数据类型[一维数组的个数][每个一维数组的长度] 例如: int [ ][ ] array = new int [2][ ...

  6. Java二维数组实现学生管理系统

    Java二维数组实现学生管理系统 一.预备知识 1.二维数组的创建1) DataType [][] name=new DataType[10][];2) DataType [][] name=new ...

  7. 杰神之JAVA二维数组(案例:走迷宫)

    Java二维数组(案例:走迷宫) 二维数组 数组的数组-二维数组的每一个元素是一个一维数组 定义方式: 数据类型[][] 数组名 = new 数据类型[长度][长度]; 数据类型[][] 数组名 = ...

  8. java二维数组的创建,java二维数组创建方法

    java动态创建二维数组,从零学java笔录-第31篇 图解二位数组在内存中存储,java二维数组动态赋值,java二维数组创建方法 二维数组的定义 type arrayName[ ][ ]; typ ...

  9. java二维数组杨辉三角_实验----Java的二维数组的应用及杨辉三角的编写

    (1) 编写一个程序,生成一个10*10的二维随机整数数组,并将该数组的每行最大值保存于一个一维数组中,将每列平均值保存于另外一个一维数组中并分别输出. (2) 编程输出杨辉三角的前10行. 找出一个 ...

最新文章

  1. WinrRar4.2 扩展名欺骗0Day
  2. AntData.ORM框架 之 读写分离
  3. 精选CSDN的ACM-ICPC五星博客
  4. Canny边缘检测算法
  5. 云图说|知道吗?在和你对话的那头,也许是个机器人哦~
  6. 前端程序员也需要知道进程和线程
  7. python访问字符串中的部分字符的操作_小白学Python-13(字符串基础与简单操作)...
  8. 【模板】堆优化 + dij +pair 存储
  9. python调用r语言函数_Python 中使用R语言
  10. 【js 分页】js 分页 方法一 【实用】
  11. JAVA实现微信授权登录(详解)
  12. Gossip 协议简介
  13. .net MVC使用GetOrgChart实现树形关系结构组织架构图
  14. 关于保险的基础知识总结
  15. Android实现截屏和截长图功能的几种方法
  16. 实战 | Kaggle竞赛:华盛顿特区首都自行车租赁预测
  17. 学习方法推荐——快速阅读
  18. 流媒体服务器 性能,流媒体服务器性能
  19. 外接显示器音频输出自动静音
  20. 网络变压器EMC 网络变压器在PCB上的设计安装要点

热门文章

  1. linux命令行抓取网页快照-(xvfb+CutyCapt)
  2. AutoCAD VBA天圆地方的放样展开图
  3. ONVIF Device Manager修改设备密码
  4. 真格量化——商品期权基本策略
  5. sqlite 设置向下递增
  6. vim 安装vim-prettier
  7. ap计算机科学a买什么书,准备AP*计算机科学A考试-第1部分
  8. xwpftablecell设置字体样式_HTML的文字样式
  9. VS toolTip1控件的使用1
  10. Python 37 进程池与线程池 、 协程