前言
今天将给大家介绍的是图论算法中的另外一个基础部分——最短路径算法;其中又分为无权最短路径,单源最短路径,具有负边的最短路径以及无圈图等;而这次将介绍常见的两个——无权最短路径以及单源最短路径。接下来就开始我们的讲解吧~~
首先还是惯例来一个:
Github传送门~~
原理
最短路径算法,顾名思义是一种用来找出从某地到另外某个地方所经过的路径长度最短的算法,如图一所示。
上图中所展示的正是Dijkstra算法查找后的结果,我们可以清楚的了解从v1点开始,到其他点的最短路径该如何选择,以及其所经过的没条边的权重;接下来我将具体介绍其实现方式:
无权最短路径:
在无权图中因为边上不存在权重,因此我们可以把每条边的权重都当做1。当我们从某个顶点开始检索的时候,我们将该节点
压入一个队列中或者是栈中(当然你也可以通过for循环来检索,不过时间复杂度会上升到O(n * n) ),然后将该节点标位已知节点,接下来检索所有与该节点相连接的节点,更新他们的路径与距离,并标位已知,接下来重复刚才的步骤,只不过
我们只对未更新过的节点(即距离无穷的节点)进行操作,直到所有节点都已知。
以下是伪代码:
int Unweighted(vertex start) {
queue Q;
vertex v, w;
enqueue(start);
// 遍历所有的节点
while(all vertex is retrieved) {
v = dequeue;
v is known;
// 遍历相邻节点
for each w adjacent to v
// 更新路径
if Dist to w is infinity {
Dist to w = Dist to v + 1;
Path to w is v;
enqueue(w);
}
}
}
伪代码中有几点需要说明:
1.遍历所有节点我们只需要保证当队列是空时即可,这和拓扑排序很相似,大家可以想一想;
2.更新路径时我们只需要保证路径未被更新过即可进行更新,因为只要我们
更新过得路径即为最短路径,关于这一点大家也可以想一想;
2.Dijkstra算法: