例如从北京到上海旅游,有多条路可以到目的地,哪条路线最短,哪条路线最省钱,就是典型的最短路径问题。
?
最短路径问题可以分为两类,第一类为:两点间最短路径。第二类为:某源点到其他各点最短路径。不同的问题类型可以用不同的算法实现,本文介绍第一类问题的Dijkstra算法实现。
?

这次新画了一个图,是时候体现一下画图技巧啦,言归正传,我们需要用有向图加邻接矩阵实现,邻接矩阵结果如下:
除此之外我们还需要维护一个最短边数组LowestEdgeArray和点到点路径长度数组PathLenArray,如下:
我们从0点出发,先解释一下上图如何理解:
第一行表示:最短边数组LowestEdgeArray索引号0存储着顶点索引:0到结束点EndVertextIndex:1,权值为13,后面的[最短路径问题 (0,1,13) ]可以不关注,主要是为了实现例如0->4,经过了哪些点,方便计算用的。
第二行表示:最短边数组LowestEdgeArray索引号1存储着顶点索引:0到结束点EndVertextIndex:2,权值为8。
后面几行也以此类推,就是在邻接矩阵图上遍历。
填写好0到5行最短边数组LowestEdgeArray数据后,计算其中最小的权值8,对应EndVertextIndex:2,并记录点到点路径长度数组PathLenArray中。2号节点被我们找到了,后面遍历1-6号节点时,不需要扫描2号点了。
我们取到的是(0,2,8),现在我们将邻接矩阵中2号点的计算并更新到最短边数组LowestEdgeArray。
我们只需要看2->3的权值5,5+8(之前取到的最小权值)<32767,因为其他点都是无穷大,但实际计算是需要挨个比较的。
更新为13,在开始找最小权值从1,3,4,5,6中扫描。
更新最短边数组LowestEdgeArray和点到点路径长度数组PathLenArray,如下:
现在只需要扫描3,4,5,6节点信息,上一个最小权值是在1号节点,把邻接矩阵中1号点的信息写入并计算。
13 < 13 + 32767,LowestEdgeArray中EndVertextIndex:3的权值13小于上一个最小值(0,1,13)的13加上邻接矩阵3号位权值32767,不更新LowestEdgeArray。
30 < 13 + 32767,LowestEdgeArray中EndVertextIndex:4的权值30小于上一个最小值(0,1,13)的13加上邻接矩阵4号位权值32767,不更新LowestEdgeArray。
32767 >?13 + 最短路径问题; 9,LowestEdgeArray中EndVertextIndex:5的权值32767 大于上一个最小值(0,1,13)的13加上邻接矩阵5号位权值9,更新LowestEdgeArray的EndVertextIndex : ? 5的权值位22。
32 >?13 +
7,LowestEdgeArray中EndVertextIndex:6的权值32?大于上一个最小值(0,1,13)的13加上邻接矩阵6号位权值7,更新LowestEdgeArray的EndVertextIndex :? ?6的权值位20。
上面4个点中找出最小权值13,(0,3,13)写入到PathLenArray中,具体变化如下:
现在只需要扫描4,5,6节点信息,上一个最小权值是在3号节点,把邻接矩阵中3号点的信息写入并计算。
30 >?13 + 6,LowestEdgeArray中EndVertextIndex:4的权值30大于上一个最小值(0,3,13)的13加上邻接矩阵4号位权值6,更新LowestEdgeArray的EndVertextIndex :? ?4的权值位19。
22 < 13 + 32767,LowestEdgeArray中EndVertextIndex:5的权值22?小于上一个最小值(0,3,13)的13加上邻接矩阵5号位权值32767,不更新LowestEdgeArray。
20 <?13 + 32767,LowestEdgeArray中EndVertextIndex:6的权值20?小于上一个最小值(0,3,13)的13加上邻接矩阵6号位权值32767,不更新LowestEdgeArray。
上面3个点中找出最小权值19,(0,4,19)写入到PathLenArray中,具体变化如下:
现在只需要扫描5,6节点信息,上一个最小权值是在4号节点,把邻接矩阵中4号点的信息写入并计算。
22 >19?+ 2,LowestEdgeArray中EndVertextIndex:5的权值22 大于上一个最小值(0,4,19)的19加上邻接矩阵5号位权值2,更新LowestEdgeArray的EndVertextIndex :? ?5的权值位21。
20 <?19?+ 32767,LowestEdgeArray中EndVertextIndex:6的权值20?小于上一个最小值(0,4,19)的19加上邻接矩阵6号位权值32767,不更新LowestEdgeArray。
上面2个点中找出最小权值20,(0,6,20)写入到PathLenArray中,具体变化如下:
现在只需要扫描5节点信息,上一个最小权值是在6号节点,把邻接矩阵中6号点的信息写入并计算。
21?< 20?+ 32767,LowestEdgeArray中EndVertextIndex:5的权值21?小于上一个最小值(0,6,20)的20加上邻接矩阵6号位权值32767,不更新LowestEdgeArray。
上面1个点中找出最小权值20,(0,5,21)写入到PathLenArray中,具体变化如下:
这样我们就得到0到其他节点的权值啦,有什么写的不妥的,大家可以多提建议。
Dijkstra的时间算法复杂度为:O(n^2)。
?
宏定义和部分定义结构体用的是之前的图的,可以参考之前的博客《》。
?
最短路径问题?
初始化访问路径结构体。
?
销毁访问路径结构体。
?
初始化结构体。
?
销毁结构体。
?
?
?
?
?
?
?
将数据压入最短边数组中。
?
?
?
?
?
?
?
?
?