【数据结构学习记录23】——最短路径

一.概述

最短路径是指:如果给定一个有向、无向网,找到一条路径,使得两个顶点间的权和最小。
比如:
在这里插入图片描述
这个图里,V0到V5的最短路径是60。(V0–V4–V3–V5

二.迪杰斯特拉(Dijkstra)算法

这个算法和前面最小生成树的算法思想一模一样,代码甚至都基本相同,只是求的对象不同。我们还得加一个数组来存最短路径距离值。如果要具体的路径,还得开一个数组来保存中间变量。
代码这篇就不详写了,可以看看别的代码。

三.弗洛伊德(Floyd)算法

怎么说呢,这是一种动态规划的思想,因为以前有接触动规,所以很好理解。只要写出我们的转移方程,就可以实现代码了。
弗洛伊德的核心思想是:如果dis(A,B) + dis(B,C) < dis(A,C),则dis(A,C)=dis(A,B) + dis(B,C)
状态转移方程为: d k ( i , j ) = m i n ( d k − 1 ( i , j ) , d k − 1 ( i , k ) + d k − 1 ( k , j ) ) d^k(i,j)=min(d^{k-1}(i,j),d^{k-1}(i,k)+d^{k-1}(k,j)) dk(i,j)=min(dk1(i,j),dk1(i,k)+dk1(k,j))
相当于,一个中介点,若通过中介点导致两个点的距离变小,那个就更新这两个点的距离。动规的思想很巧妙,得多理解。
所以,我们三个循环就可以完成:

  1. 第一层循环:遍历所有点,作为中介点。(遍历k)
  2. 第二次循环:遍历所以的起始点。(遍历i)
  3. 第三次循环:遍历所有的结束点。(遍历k)
    所以代码就放这里了:
//k为中间点 
for(k = 0; k < G.vexnum; k++)
{
    
    
    //v为起点 
    for(i = 0 ; i < G.vexnum; i++)
    {
    
    
        //w为终点 
        for(j =0; j < G.vexnum; j++)
        {
    
    
            if(D[i][j] > (D[i][k] + D[k][j]))
            {
    
    
                D[i][j] = D[i][k] + D[k][j];
                //更新最小路径 
            }
        }
    }
}

最后,领接矩阵D则是任意两个点的最短路径的值。
如果要路径的话,则开一个数组,在更最内层判断力更新路径即可。

四.后记

感觉这篇写的好水,但是毕竟是我的笔记,我康得懂就行惹。。。。

猜你喜欢

转载自blog.csdn.net/u011017694/article/details/111151735