单源最短路径Dijkstra算法的思想、详细步骤、代码

目录

一、算法思想

二、算法详细步骤

三、伪代码 + C++代码

四、算法复杂度分析

五、算法改进

六、应用案例


一、算法思想

1、Dijkstra 算法是用来求解单源最短路径问题的经典算法,其本质上是一个贪心算法。

   (PS: 求任意两个结点之间最短路径的有 Floyd 算法)

2、算法的基本思想是:设置一个顶点集合 S 并不断地做贪心选择来扩充这个集合。

3、该算法适用:1)边权为,2)有向无向都适用

有一些相关的性质:

  1. 对于边权为正的图,任意两个结点之间的最短路,不会经过重复的结点。
  2. 对于边权为正的图,任意两个结点之间的最短路,不会经过重复的边。
  3. 对于边权为正的图,任意两个结点之间的最短路,任意一条的结点数不会超过 n ,边数不会超过 n - 1 。

 

二、算法详细步骤

假设:

        1)已知带权图 G = (V, E)

       - V: 顶点(Vertex)的集合

       - E: 边(Edge)的集合

                      - 边 e = (u, v), u \epsilon V, v \epsilon V

        2)一个顶点属于S当且仅当从源到该顶点的最短路径长度已知。

        3)  数据结构:数组d,为记录当前每个顶点所对应的最短特殊路径长度(源v0到该顶点)。

算法步骤:

1、S 中初始时仅包含源 v0

2、从顶点集合 { V - S } 中选取最短特殊路径长度最短的顶点,并将其加入 S

3、对数组 d 进行更新(更新条件:若源 v0 通过某个顶点到该顶点的路径比原先 d 数组保存的小)

 

三、伪代码 + C++代码

1、伪代码

清除所有点的标号  // 属于集合S的标记
设d[0] = 0, 其他d[i] = INF  // initial
循环n次 {
    在所有未标号结点中,选出d值最小的结点x  // 从{V - S}中选出从源出发距离最短的顶点
    给结点x标记  // 加入集合S
    对于从x出发的所有边(x,y),更新d[y] = min{d[y], d[y]+w(x, y)}  // 更新所有x的出边顶点
} 

 

2、C++代码实现

memset(v, 0, sizeof(v));
for(int i = 0; i < n; i++) d[i] = (i==0 ? 0 : INF);
for(int i = 0; i < n; i++) {
    int x, m = INF;
    for(int y = 0; y < n; y++) if(!v[y] && d[y]<=m) m = d[x=y];
    v[x] = 1;
    for(int y = 0; y < n; y++) d[y] = min(d[y], d[x] + w[x][y]);
}

 

四、算法复杂度分析

 

五、算法改进

 

六、应用案例

 

更新:2021年5月3日

未完,待续。。。

 

 

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页