边 | 权值 |
0 --> 4 | 25 |
0 --> 2 | 10 |
对应的最短路径数组为[0, 4, 10, INFINIT, 25, INFINIT, INFINIT]。我们再去表里面最小权值的边0 --> 2,并比较节点2的所有邻接节点:
对应更新后的表如下:
边 | 权值 |
0 --> 4 | 25 |
0 --> 3 | 15 |
0 --> 5 | 18 |
对应的最短路径数组为[0, 4, 10, 15, 25, 18, INFINIT]。我们再取里面权值最短的边0 --> 3:
对应的表如下:
边 | 权值 |
0 --> 4 | 20 |
0 --> 5 | 18 |
这一步比较有意思,我们通过节点3的时候又访问到节点4了,之前我们计算出来它的最短路径是25,而通过节点3得到的最短路径是20。于是我们要更新最小路径数组里对应的值,得到对应的数组为[0, 4, 10, 15, 20, 18, INFINIT]。这个时候,我们再取表里面最短的路径0 --> 5:
在节点5这一步,它又可以遍历到节点4,而按照它的距离加上到节点4的边的权值,这个距离值是30,明显大于前面我们计算出来的20。所以,这里不会更新最短路径数组。这样,我们得到的表如下:
边 | 权值 |
0 --> 4 | 20 |
而这里最短路径数组还是和原来的一样:[0, 4, 10, 15, 20, 18, INFINIT]。现在,我们再取最后的边0 --> 4:
我们可以得到对应的表如下:
边 | 权值 |
0 --> 6 | 24 |
最短路径数组是[0, 4, 10, 15, 20, 18, 24]。我们再取边0 --> 6的时候已经找不到更短的可以更新的节点了。这样,我们就按照这个过程遍历更新了所有的节点。
要点
在上述算法的演示过程中,我们用一个表来保存相对于源节点来说它当前能到达的节点的距离。每次取里面最短的那个边,然后再去根据这个边对应的点去检查更新它的邻接节点。而每次在取走最短路径的边并更新到邻接节点距离的值的过程相当于将当前最短路径的这个点给抹去了。
在这一步,我们可能会有几个疑问。一个是为什么我们每次要取权值最小的边?而且,我们每次取这个最小权值的边为什么是正确的呢?这是怎么保证的?我们可以以前面示例中的一些过程来说明。以最开始选择0节点的两个邻接节点为例: