从零开始学数据结构系列之第四章《弗洛伊德算法详解》

发布于:2024-08-10 ⋅ 阅读:(140) ⋅ 点赞:(0)

文章目录


算法详解

以下都用这个图进行讲解
在这里插入图片描述
这算法本质上也是一种暴力求解,通过两个数组来进行求解

P 数组 ------- 存放的是两点直接的前驱
D 数组 ------- 存放的是两点直接的最短距离

​   算法的本意是,在两个顶点间,以此加入我们图的每一个顶点来比较他的权值,当他的权值比原本的权值要小的话,则替代掉原本的权值

核心:试探法,通过加入不同的点进行中转,选择出最优解

1:
在这里插入图片描述
首先先进行初始化数组

​   首先我们的D数组是存放两个点之间的最短距离,首先我们可以看它的对角线,它的对角线的距离就是它本身到自己的距离,也就是 v 1到 v 1、v2到 v2、v3到 v3、v4到 v4的距离,所以我们对角线的距离赋值都为0

​   其次我们可以从上图中观察到它 v 1到 v2的距离是1。那我们复制给它1.

​   v 1到 v3的距离,由于是没有路径可以到达它,那所以我们赋值为 max

​   那根据以上的说辞,那我们可以将D数组整体给初始化成如上图所示

​   接下来我们开始初始化P数组,那P数组是存放他的前驱的位置的,那 v 1到 v 1之间的前驱,它的路径是没有的,所以我们将它的前驱赋值为-1,同理我们也可以观察到它的对角线,也就是它本身到自己的距离都是没有前驱。所以我们对角线都赋值为-1

​   之后我们通过观察发现 v 一到 v2或者 v 一到 v4之间,那它的前驱都是它自己本身也就是0,那这一个0的话,我们可以看到前面的迪杰斯特拉算法中算法部分讲解也有说到。

​   那根据我们之前的迪杰斯特拉算法中,那我们可以根据它 v 1、v2、v3、v4对应的数组中的0123来进行去赋值.

​   那同理,我们也可以根据一直往下走,我们可以看到 v2、v3、v4,那它到其他节点的前驱,就是它自己的本身达不到的那我们就赋值为-1

2:
在这里插入图片描述
根据以上我们初始化完毕,那那接下来我们先看 v 1节点

​   那我们的弗洛伊德算法,那它本质就是暴力破解,它每个节点之间的那种距离。比如说每个节点到节点之间,我们再插入一个节点来看,是否能获取它的最短路径

​   那我们标黄的就是它不会变遍历的节点,那它不会遍历的节点,就是 v 1,它那一行列与它的对角线,那空白的位置就是它会遍历的地方

​   那我们可以看到空白的地方就是 v2到 v3之间的距离。那我们根据弗洛伊德算法,我们在 v2和 v3之间插入一个 v 1节点,那看它 v2到 v 1到 v3的距离,会不会比 v2到 v3距离短

​   那我们可以看到 ,本身 v2到 v3的距离是二,那如果我们再插上 v 1节点的话,那我们可以看到表上 v 1到 v3距离的是 max,那我们 max 加上任何数都是 max,所以的话我们不会对该节点进行一个更新

​   同样我们接下来看到 v2和 v4节点,我们看 v2到 v4节点,中间插上一个 v 一节点,会不会使它的最短路径更短,那接下来我们可以看到 v2到 v4节点的距离是二。那如果我们加上 v 一节点的话,就是 v2到 v 一的距离周再加上一个 v4,那也就是2加3,那就是等于5,很明显大于我们之前的距离,那我们同样也不选择更新这个节点

​   接下来我们看 v3到 v4节点,那我们 v3到 v4节点中间再插个 v 一节点的话,同样也是 max,加上它的最短路径,那我们同样也是不更新.

​   同理,遍历以下的节点,那我们都会发现它都是比原先节点要大。那所以我们都不更新,所以P数组和D数组的所有内容均不更新

3:
在这里插入图片描述
  然后我们可以看到 v 1节点的话,它是没有使任何内容进行更新的那我们再重新看到 v2节点,那 v2节点的话,那同理跟 v 一节点一样,那它的对角线以及它那一行列都不会进行一个遍历算法。

​   那同理,我们也为了节约时间,那我们详细步骤可以看我们上面的步骤。二那如果不会进行更新的节点,那就不说了

​   那那我们可以看到我们标红的,也就是它会更新的节点,我们再重新过来看一下

​   我们对比 v 1加入后的图来看,我们 v 一到 v3的距离之间,我们再插上一个 v2,也就是 v 一到 v2之后再到 v3的距离,那也就是一加上二等于三。那三的值很明显是小于一个 max 的那我们选择更新.我们的 p 数组进行更新的话,那我们的D数组也会进行一个相应的更新

​   那可以看到,由于我们是插入 v2节点之后呢,它的最短路径会缩小。那我们 v 一到 v3之间的距离的话,就是变成了 v 1到 v2到 v3的距离。那我们 v3的前驱就是 v2,那所以我们复制给它为1.

​   同理,我们可以看到 v3到 v4之间插入一个 v2的节点,那这样的话,最短路径就变成二加上二等于四,那明显是小于 v3到 v4之间的八,那我们选择进行更新。那同理我们也更新它的前驱数组,那也就是 v2,那也就是1.

​   同理,v4到 v3之间的距离也是一样的,那 v4到 v3的距离原本是八,那我们插入一个 v2节点,那就变成 v4到 v2之后再到 v3。那我们最短路径的话,也就是二加上二,那等于四,那是小于它原先最短路径的八,我们选择更新它的数组以及它的前驱

​   之后,那我们 v2节点的加入已经便利完了

4:
在这里插入图片描述
  那这里的图也是跟弗洛伊德算法详解中2,3的步骤很像,那这里就不再过多的进行一个讲解

往期回顾

1.【第一章】《线性表与顺序表》
2.【第一章】《单链表》
3.【第一章】《单链表的介绍》
4.【第一章】《单链表的基本操作》
5.【第一章】《单链表循环》
6.【第一章】《双链表》
7.【第一章】《双链表循环》
8.【第二章】《栈》
9.【第二章】《队》
10.【第二章】《字符串暴力匹配》
11.【第二章】《字符串kmp匹配》
12.【第三章】《树的基础概念》
13.【第三章】《二叉树的存储结构》
14.【第三章】《二叉树链式结构及实现1》
15.【第三章】《二叉树链式结构及实现2》
16.【第三章】《二叉树链式结构及实现3》
17.【第三章】《二叉树链式结构及实现4》
18.【第三章】《二叉树链式结构及实现5》
19.【第三章】《中序线索二叉树理论部分》
20.【第三章】《中序线索二叉树代码初始化及创树》
21.【第三章】《中序线索二叉树线索化及总代码》
22【第三章】《先序线索二叉树理论及线索化》
23【第三章】《先序线索二叉树查找及总代码》
24【第三章】《后续线索二叉树线索化理论》
25【第三章】《后续线索二叉树总代码部分》
26【第三章】《二叉排序树基础了解》
27【第三章】《二叉排序树代码部分》
28【第三章】《二叉排序树代码部分》
29【第三章】《平衡二叉树基础概念》
30【第三章】《平衡二叉树的平衡因子》
31【第三章】《平衡二叉树的旋转基础详解》
32【第三章】《平衡二叉树的旋转类型图文详解》
33【第三章】《平衡二叉树的旋转类型总结及总代码》
34【第三章】《哈夫曼树简单了解》
35【第三章】《哈夫曼树的构造方法》
36【第三章】《哈夫曼编码构造及代码》
37【第四章】《图的定义》
38【第四章】《图的基本概念和术语》
39【第四章】《图的存储结构》
40【第四章】《图的遍历之深度优先遍历》
41【第四章】《广度优先遍历BFS》
42【第四章】《图的遍历总代码》
43【第四章】《最小生成树概念》
44【第四章】《最小生成树的应用举例》
45【第四章】《prim算法(普里姆算法)详解》
46【第四章】《prim算法(普里姆算法)详解2》
47【第四章】《prim算法(普里姆算法)详解3》
48【第四章】《prim算法(普里姆算法)讲解汇总》
49【第四章】《prim算法(普里姆算法)代码讲解》
50【第四章】《prim算法(普里姆算法)总代码》
51【第四章】《克鲁斯卡尔算法思路介绍》
52【第四章】《克鲁斯卡尔算法步骤思路1》
53【第四章】《克鲁斯卡尔算法步骤思路2》
54【第四章】《克鲁斯卡尔算法应用场景-公交站问题》
55【第四章】《克鲁斯卡尔算法判断回路问题》
56【第四章】《克鲁斯卡尔算法步骤回顾》
57【第四章】《克鲁斯卡尔算法代码初始化详解》
58【第四章】《克鲁斯卡尔算法总代码详解》
59【第四章】《了解最短路径》
60【第四章】《迪杰斯特拉算法了解》
61【第四章】《Dijkstra 迪杰斯特拉算法图解》
62【第四章】《Dijkstra 迪杰斯特拉算法总代码》
63【第四章】《弗洛伊德(floyd)算法简介》


网站公告

今日签到

点亮在社区的每一天
去签到