Dijkstra算法是一种用于在加权图中找到单个源点到所有其他顶点的最短路径的算法。这个算法是由荷兰计算机科学家艾兹格·迪科斯彻(Edsger W. Dijkstra)在1956年提出的。Dijkstra算法适用于处理带有非负权重的图。
以下是Dijkstra算法的基本步骤:
初始化:创建一个集合S,用于存储已经找到最短路径的顶点,初始时S为空。为每个顶点分配一个初始的最短路径估计值,对于源顶点,这个值设为0,对于其他顶点设为无穷大(表示尚未找到路径)。
选择顶点:从未加入S的顶点集合中,选择一个具有最小估计值的顶点k。
松弛操作:对于顶点k的所有邻接顶点j,进行松弛操作。松弛操作是检查通过顶点k到达j的路径是否比当前已知的路径更短。如果通过k到达j的路径长度(即顶点k的最短路径估计值加上k到j的边的权重)小于j的当前最短路径估计值,那么更新j的最短路径估计值为通过k到达j的路径长度。
更新S集合:将顶点k加入到S中,表示k的最短路径已经被确定。
重复过程:重复步骤2和3,直到所有顶点都被加入到S中,或者只剩下一个顶点的最短路径估计值没有被更新过(这意味着所有其他顶点的最短路径都已找到)。
结束条件:当所有顶点都被加入到S中,或者没有更多的顶点可以进行松弛操作时,算法结束。
以下是Dijkstra算法的伪代码示例:
procedure Dijkstra(Graph, source)
for each vertex v in Graph
distance[v] := INFINITY
predecessor[v] := UNDEFINED
end for
distance[source] := 0
Q := the set of all vertices in Graph
while Q is not empty
u := vertex in Q with min distance[vertex]
remove u from Q
for each neighbor v of u
alt := distance[u] + length(u, v)
if alt < distance[v]
distance[v] := alt
predecessor[v] := u
end if
end for
end while
end procedure
Dijkstra算法的时间复杂度取决于图的表示方式和使用的优先队列。如果使用邻接矩阵,时间复杂度是 O(V^2),其中 V 是顶点数。如果使用邻接表,并以二叉堆作为优先队列,时间复杂度是 O((V + E) log V),其中 E 是边数。存在更高效的数据结构,如斐波那契堆,可以将时间复杂度降低到 O(E + V log V)。