[最短路径弗洛伊德算法]三层循环顺序问题

[最短路径弗洛伊德算法](三层循环顺序问题)

先上代码

for(int i=0;i<city;i++)
			for(int j=0;j<city;j++)
				for(int k=0;k<city;k++) {
					if(length[j][i]+length[i][k]<length[j][k])
						length[j][k]=length[j][i]+length[i][k];			
					}

众所周知,弗洛伊德是一个利用三层循环来暴力枚举所有可能情况的算法。且其关键是中间结点一定要放在最外层循环。
那么,问题来了:为什么中间结点要放在最外面呢?,有人甚至一度认为放在其他位置也是对的(我)。。。(是不是也有你)。。。
[最短路径弗洛伊德算法]三层循环顺序问题_第1张图片
我在网上搜了一下,感觉说的不是很清楚。经过自己的理解后,希望能把这个问题说清楚一点吧,也希望可以帮助大家更好地理解这个算法。
我们知道,最短路径是靠邻接矩阵说话的,那么,请跟着我一起想一想分别把中间结点放在第一层,第二层,第三层时,邻接矩阵是如何随着循环而变化的。

放在第一层:

以我的代码为例,邻接矩阵是length。
此时length是一行一行逐行更新的,所有行更新完后,更换中间结点然后重新从第一行开始逐行更新。更换到最后一个结点时,所有length[j][k]还有一次更新的机会,而且此次更新利用了之前所有更新过的数据。

放在第二层:

length也是逐行更新,但是是先利用初始未更新过的数据去更新第一行若干遍,再去更新第二行若干遍。。。更新到最后一行就结束了。我们可以想到,除了在更新最后一行时,更新时用的数据都不一定是最短路径。就是说,**利用的是为更新完全的数据。**并且最重要的是,之后就没有了再次更新的机会。通俗地说,你用初始数据更新完第一行之后就不管它了。这样说大家应该就能理解了。

放在第三层:

length是利用未更新全面的数据单个更新若干次,之后就没有了再次更新的机会,与放在第二层类似,在下就不过多赘述了。

至此,大家应该能明白为什么中间结点变量要放在循环的最外层了吧。
如果本文能够帮助到你,我非常荣幸。点个赞让我开心一下不过分吧。
[最短路径弗洛伊德算法]三层循环顺序问题_第2张图片

欢迎留个评论大家一起讨论。

你可能感兴趣的:(数据结构)