Dijkstra
void dijkstra(Table T)
{
vertex v, w;
for(;;)
{
v = smallest unknown distance vertex;
if(v == NotAVertex)
break;
T[V].known = true; //每轮选取一个最短路径节点v进入生成树
for each w adjacent to v
if(!T[w].know)
//更新非生成树中各点的权值
}
}
Dijkstra算法不能处理负权值
使用中发现,权重为负,算法依然可能正常结束。但是Dijkstra 每一步都确定一个最短路径,并加入生成树中。节点只入队一次,无法更新已进入树中的节点的路径。这也是假设路径非负的直接结果。
对应《数据结构与算法分析——C语言描述》P304的改进算法
//不记录节点是否已经进入树中
//每次选取最短路径节点进入队列
//根据当前最短路径节点 更新 其它节点的路径
去掉了判断节点是否已经加入生成树中,依然更新最短路径。所以会产生节点重复进队的情况。从这里也可以看出Dijkstra算法速度快的原理。
但P304的改进程序,内循环的多次运行,导致遇到负值圈,算法无限循环,无法停止。
Floyd
Floyd的思路更简单。选取其它节点作为中继,来relax当前路径。
当同样无法处理 负值圈
Bellman-Ford
可以检测负值圈