dijkstra算法_dijkstra算法

3ccc077ea6e43772879baccb7019dc83.png

dijkstra算法迪杰斯特拉算法)是荷兰科学家E.W.Dijkstra于1959年提出的寻路算法,是目前公认的最好的求解最短路径的方法。堆优化后时间复杂度可达O((m+n)log(m)),但缺点是不能处理负权边。

负权边是什么:负权边,即权重为负的边。我们可以将每一条边的权重可以认为是从a端到b市面的过路费,而负权就是有土豪在地上撒钱,不但没有过路费还会让你总花费变少。

其算法步骤如下

  1. 将所有的顶点分为两个部分:已知最短距离的顶点集合P和未知最短距离的顶点集合Q。最开始的时候,已知最短距离的顶点集合中只有源点。
  2. 初始化distance数组,将源点s到自己的距离设置为0,到其他顶点的距离姑且设置为Infinity。
  3. 依据distance数组,在未知顶点集合Q中选出距离源点最近的一个顶点u,放入P中,并考察所有以u为起点的边,以u作为中转点,检验是否能够减短源点到其他点的距离。如果有,就更新distance数组。这一步又叫松弛(relaxation)操作。
  4. 重复上一步骤,直到Q中没有顶点。
松弛操作:更新两点间的最短路径。就是对于每个边e(v,w),将源点s到w的距离更新为:原来源点s到w的距离 和 源点s到v的距离加上v到w的距离 中较小的那个。其原理是著名的“三角形两边之和大于第三边”定律。

a8cced81cbe97ab7f4782cad90ffc4ad.png

下面我们图解整个算法过程:

75c40e6a515ea559ea1e8e8e71630dea.png

从A出发,到达A

var 

c527dc5cf7109cf078cd491884d4d3f9.png

寻找A的没被访问的邻居顶点B,D,分别计算它们到A的距离

A

7c7cfb610d00a0f992d8b21e16bf113a.png

将距离最短的D放到S集合中

var 

寻找D的没被访问的邻居顶点B,C,E,分别计算它们到A的距离

A

D到B,D的距离一样,都放入结果集

var 

165f30a2e8a689819c889456ac088aad.png

这时可以从B与C出发,但B已经没有未访问的邻居,而C有一个E

A->D->C->E = S.C+ E.weight = 3+3 = 6

将E放到结果集中

var 

4be8758f3bbf17190ecc7c4e96711d47.png

我们顺着上面的思路,使用链式前向星与BFS实现该算法。BFS会在循环中将它的所有邻居放在一起比较到源点的距离,因此我们还需要排序(这在其他语言,可以用到优先队列)。

var 

c9d8df9ec735a9aef03172c6230d9044.png
对于无权图,所谓的最短路径其实是指两顶点之间经过的边数最少的路径。

如果 你不会用链式前向星,改用边集数组来表示图也很简单

var 

0599ced64c59088d362366cde3511020.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值