Dijkstra算法是由荷兰计算机科学家Edsger Wybe Dijkstra于1959年提出的一种解决有向加权图中单源最短路问题的算法,其中要求加权图中不可有负权边。
|
|
|
|
|
|
---|---|---|---|---|---|
初始状态 | 0 |
|
|
|
|
|
|
|
|
|
|
---|---|---|---|---|---|
第一次迭代后 | 0 | 10 | 3 | 20 |
|
|
|
|
|
|
|
---|---|---|---|---|---|
第二次迭代后 | 0 | 5 | 3 | 20 | 18 |
|
|
|
|
|
|
---|---|---|---|---|---|
第三次迭代后 | 0 | 5 | 3 | 10 | 18 |
|
|
|
|
|
|
---|---|---|---|---|---|
第四次迭代后 | 0 | 5 | 3 | 10 | 18 |
|
|
|
|
|
|
---|---|---|---|---|---|
第五次迭代后 | 0 | 5 | 3 | 10 | 18 |
|
|
|
|
|
|
---|---|---|---|---|---|
初始状态 | 0 |
|
|
|
|
第一次迭代后 | 0 | 10 | 3 | 20 |
|
第二次迭代后 | 0 | 5 | 3 | 20 | 18 |
第三次迭代后 | 0 | 5 | 3 | 10 | 18 |
第四次迭代后 | 0 | 5 | 3 | 10 | 18 |
第五次迭代后 | 0 | 5 | 3 | 10 | 18 |
不难观察到,Dijkstra算法的特点主要是从起点开始,“由近及远,层层扩展”,越靠前处理的点离起点越近,最后一个处理的点一定离起点最远。
所以,依据算法每找到一个顶点后,该顶点对应的
而最后一次迭代得到的所有
故Dijkstra算法解决的是有向图中的单源最短路问题。
步骤概括:
流程图:
提醒:这里读者一定要反复仔细体会
Dijkstra算法的数学证明:
由算法的数学描述,可知:
只有命题:“每次从
可用广义数学归纳法证明,设起点为
综上所述,该命题得证,故算法正确。
Dijkstra算法要求有向图中不得有负权边,如果图中有负权边,则在之前的证明过程中:
这里举一个简单的例子供读者自行对照理解:
设有向图中,共有
传统Dijkstra算法中主要操作有:
在上述对于传统Dijkstra算法的时间复杂度分析中,我们可知,(尤其是稀疏图中)从
因此对于顶点的有效排序可以大大地提高算法的性能,常用的方法有:小顶堆或优先队列:
注意:优先队列优化中,新的顶点二元组入队时,旧的二元组依然在优先队列中,因此每次出队的元素可能会有杂音,如何识别并去除这些杂音是这种优化方式需要考虑的。
事实上,Dijkstra算法同样可以处理无向图中的单源最短路问题(无向图其实可看做一种特殊的有向图),但在这种情况下,要对算法做一些修改:标记已经访问过的边,在寻找邻居时不沿已标记过的边寻找。
Dijkstra算法的空间复杂度视具体实现方法而定,采用邻接矩阵的存图方式的空间复杂度为
算法具体代码实现多种多样,留作读者自行思考,在此不再赘述。
绝对原创,转载请注明出处。 才疏学浅,如有错误,望不吝赐教