最短路径问题——Dijkstra算法
一.基础知识
Dijkstra算法(迪杰斯特拉算法)
三个数组
(1)final[ ]:标记各顶点是否已找到最短路径
(2)dist[ ]:最短路径长度,无路径用∞表示
(3)path[ ]:路径上的前驱,如:path[2]=1表示由1到2的路径。起点无前驱,path置-1;无路径无前驱,path置-1
二.表示过程
起始点:V0
初态三数组表:
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
final | √ | × | × | × | × |
dist | 0 | 10 | ∞ | ∞ | 5 |
path | -1 | 0 | -1 | -1 | 0 |
此时dist为V0不经过×点到各顶点的最短路径
找到最小的dist,将对应的final置√,此时V4已找到最短路径
通过新加入顶点V4 与原V0的dist表 对比选最小值,更新dist表
即:通过V4找更小
V4连通V1、V2、V3
对应路径长度分别为:3+5=8、9+5=14、2+5=7
8<10更新、14<∞更新、7<∞更新
更新dist及path表
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
final | √ | × | × | × | √ |
dist | 0 | 8 | 14 | 7 | 5 |
path | -1 | 4 | 4 | 4 | 0 |
找到×中最小的dist,将对应final改为√
通过新加入的V3与当前的dist比较,选择小的更新数组
V3有到V0和V2的路径,只有V2是×
到V2路径长度为5+2+6=13<14,更新dist[2]和path[2]
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
final | √ | × | × | √ | √ |
dist | 0 | 8 | 13 | 7 | 5 |
path | -1 | 4 | 3 | 4 | 0 |
选择×中最小的dist,将其final置√
最后通过新加入的V1,对比其到V2的路径长度5+3+1=9<13,更新dist[2]和path[2]
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
final | √ | √ | × | √ | √ |
dist | 0 | 8 | 9 | 7 | 5 |
path | -1 | 4 | 1 | 4 | 0 |
完成,将V2的final置√
V0 | V1 | V2 | V3 | V4 | |
---|---|---|---|---|---|
final | √ | √ | √ | √ | √ |
dist | 0 | 8 | 9 | 7 | 5 |
path | -1 | 4 | 1 | 4 | 0 |
通过表格观察得到
V0到V2的最短路径长度为:dist[2]=9
最短路径通过path数组得到:2←1←4←0
三.时间复杂度
过程回顾:
(1)循环遍历所有顶点,找到×且当前dist最小,修改final。需要O(n)
(2)检查所有邻接自Vi的顶点,观察是否是×且小于dist,更新dist和path,需要O(n)
总共需要2O(n),即O(n)
一个n-1轮,即(n-1)*O(n),即O(n²)
四.用于负权值带权图
从V0开始
V0 | V1 | V2 | |
---|---|---|---|
final | √ | × | × |
dist | 0 | 10 | 7 |
path | -1 | 0 | 0 |
V0 | V1 | V2 | |
---|---|---|---|
final | √ | × | √ |
dist | 0 | 10 | 7 |
path | -1 | 0 | 0 |
V0 | V1 | V2 | |
---|---|---|---|
final | √ | √ | √ |
dist | 0 | 10 | 7 |
path | -1 | 0 | 0 |
则从V0到V2最短路径长度为7,最短路径为0→2
但V0到V2最短路径长度为10+(-5)=5,最短路径为0→1→2
Dijkstra算法出现问题,因此Dijkstra算法不适用于有负权值的带权图