【数据结构】最短路径——弗洛伊德算法(详解版)

示例

问:求各地之间的最短路径长度及最短路径

在这里插入图片描述
答:

起点终点最短路径长度最短路径
AB2A->B
AC4A->B->D->C
AD3A->B->D
BA1B->A
BC2B->D->C
BD1B->D
CA4C->B->A
CB3C->B
CD4C->B->D
DA5D->C->B->A
DB4D->C->B
DC1D->C

算法思想

对于上述例子:
已知直接相连的顶点之间的路径(无中转顶点)

  1. 允许A作为中转顶点,求出各顶点之间的最短路径
  2. 允许A、B作为中转顶点,求出各顶点之间的最短路径
  3. 允许A、B、C作为中转顶点,求出各顶点之间的最短路径
  4. 允许A、B、C、D作为中转顶点,求出各顶点之间的最短路径

抽象之后:
若有n个顶点(V0、V1、…Vn-1),需要进行n步操作,每次向中转顶点中增加一个新的顶点
  1、允许 V0 作为中转顶点,求出各顶点之间的最短路径
  2、允许 V0、V1 作为中转顶点,求出各顶点之间的最短路径
    ……
  n、允许 V0、V1、…Vn-1 作为中转顶点,求出各顶点之间的最短路径

算法过程

用到两个表记录数据:

  • 路径长度表:记录两个顶点之间的最短路径长度
  • 路径表:记录两个顶点之间的中转点
    • -1:无中转点
    • 0:中转点为A
    • 1:中转点为B
    • 2:中转点为C
    • 3:中转点为D

初始状态的路径长度表如下:(和图的邻接矩阵一致)
在这里插入图片描述
初始状态的路径表如下:
在这里插入图片描述


第一步:允许A作为中转顶点

起点终点刚加入的中转顶点原路径长度新路径长度是否修改
ABA20+2=2
ACA60+6=6
ADA0+∞=∞
BAA11+0=1
BCA1+6=7
BDA11+∞=∞
CAA∞+0=∞
CBA3∞+2=∞
CDA∞+∞=∞
DAA∞+0=∞
DBA∞+2=∞
DCA1∞+6=∞

在这里插入图片描述在这里插入图片描述

第二步:允许A、B作为中转顶点

起点终点刚加入的中转顶点原路径长度新路径长度是否修改
ABB22+0=2
ACB62+7=9
ADB2+1=3
BAB10+1=1
BCB70+7=7
BDB10+1=1
CAB3+1=4
CBB33+0=3
CDB3+1=4
DAB∞+1=∞
DBB∞+0=∞
DCB1∞+7=∞

在这里插入图片描述
第三步:允许A、B、C作为中转顶点

起点终点刚加入的中转顶点原路径长度新路径长度是否修改
ABC26+3=9
ACC66+0=6
ADC36+4=10
BAC17+4=11
BCC77+0=7
BDC17+4=11
CAC40+4=4
CBC30+3=3
CDC40+4=4
DAC1+4=5
DBC1+3=4
DCC11+0=1

在这里插入图片描述
第四步:允许A、B、C、D作为中转顶点

起点终点刚加入的中转顶点原路径长度新路径长度是否修改
ABD23+4=7
ACD63+1=4
ADD33+0=3
BAD11+5=6
BCD71+1=2
BDD11+0=1
CAD44+5=9
CBD34+4=8
CDD44+0=4
DAD50+5=5
DBD40+4=4
DCD10+1=1

在这里插入图片描述
至此,已求完所有的最短路径长度

接下来,根据 路径表 求最短路径,图中蓝色部分表示有中转顶点(值不为-1)
在这里插入图片描述
A至B、B至A、B至D、C至B、D至C直接就是最短路径,无中转点

A至C:

  • 查A至C的数值为3,表明A与C之间有中转点为D
    • 查A至D的数值为1,表明A与D之间有中转点为B
      • 查A至B的数值为-1,表明A与B之间无中转点
      • 查B至D的数值为-1,表明B与D之间无中转点
    • 查D至C的数值为-1,表明D与C之间无中转点

所以最终得到A至C的最短路径为A->B->D->C

A至D:

  • 查A至D的数值为1,表明A与D之间有中转点为B
    • 查A至B的数值为-1,表明A与B之间无中转点
    • 查B至D的数值为-1,表明B与D之间无中转点

所以最终得到A至D的最短路径为A->B->D

B至C:

  • 查B至C的数值为3,表明B与C之间有中转点为D
    • 查B至D的数值为-1,表明B与D之间无中转点
    • 查D至C的数值为-1,表明D与C之间无中转点

所以最终得到B至C的最短路径为B->D->C

C至A:

  • 查C至A的数值为1,表明C与A之间有中转点为B
    • 查C至B的数值为-1,表明C与B之间无中转点
    • 查B至A的数值为-1,表明B与A之间无中转点

所以最终得到C至A的最短路径为C->B->A

C至D:

  • 查C至D的数值为1,表明C与D之间有中转点为B
    • 查C至B的数值为-1,表明C与B之间无中转点
    • 查B至D的数值为-1,表明B与D之间无中转点

所以最终得到C至D的最短路径为C->B->D

D至A:

  • 查D至A的数值为2,表明D与A之间有中转点为C
    • 查D至C的数值为-1,表明D与C之间无中转点
    • 查C至A的数值为1,表明C与A之间有中转点B
      • 查C至B的数值为-1,表明C与B之间无中转点
      • 查B至A的数值为-1,表明B与A之间无中转点

所以最终得到D至A的最短路径为D->C->B->A

D至B:

  • 查D至B的数值为2,表明D与B之间有中转点为C
    • 查D至C的数值为-1,表明D与C之间无中转点
    • 查C至B的数值为-1,表明C与B之间无中转点

所以最终得到D至B的最短路径为D->C->B

  • 7
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序鸡

如果帮到您,点个赞鼓励一下吧。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值