时间:2025年 01月 11日
作者:小蒋聊技术
邮箱:wei_wei10@163.com
微信:wei_wei10
音频:喜马拉雅
大家好,欢迎来到“小蒋聊技术”!我是你们的技术小助手——小蒋。今天,我要和大家聊聊一个非常实用且有趣的算法——Dijkstra 算法。
大家是不是也有过这样的经历:出门旅行,地图上标着四通八达的道路,可我怎么知道哪条路最短、最快呢?你是不是也曾经遇到过这种困惑——“这条路太长了吧?我能不能走得更快些?”
好了,今天我就给大家介绍一个聪明的小助手——Dijkstra 算法!它能帮助你解决这个问题,让你在复杂的路网中找到最短的路径。听起来是不是很酷?那就来和我一起深入了解吧!
1. Dijkstra 算法:解锁最短路径的秘密武器
首先,让我们从一个简单的例子开始。如果你要从你家(假设是图中的 A 点)出发,去一个从没去过的城市(假设是图中的 D 点),而城市之间的道路长短不一。你怎么知道哪条路最短,能让你尽量少走弯路?
你是不是想到了手机地图?对的,Dijkstra 算法就是我们生活中“导航”的算法——它帮助你从出发点开始,选择一条最短的路径,一步步到达目的地。
2. Dijkstra 算法:每一步都选择最短的路
Dijkstra 算法的核心思想很简单:每次选择离自己最近的城市(或者节点),然后继续向前走,直到你遍历到所有城市。这就像你在玩超级玛丽游戏,每一次你选择走的路线都是最短、最快的,直到你打败所有的敌人,走到最终胜利——到达目的地。
Dijkstra 算法的步骤:
- 初始化:从起点出发,将所有城市的距离初始化为无穷大,只有起点的距离为 0。
- 选择最近的城市:从已遍历的城市中选择一个距离最小的城市,标记为已遍历。
- 更新距离:根据当前城市更新与其他城市之间的最短路径。
- 重复:直到所有城市都被遍历完,得到从起点到所有其他城市的最短路径。
3. Dijkstra 算法的示例:从家到目的地
为了让大家更清楚地理解,让我们用一个简单的图来说明如何使用 Dijkstra 算法。
假设我们有以下的城市和道路图:
假设你从城市 A 出发,目标是找到到达城市 D 的最短路径。
Dijkstra 算法过程:
- 初始化:将所有城市的距离初始化为无穷大,起点城市 A 的距离设为 0。
城市A | 城市B | 城市C | 城市D |
0 | ∞ | ∞ | ∞ |
- 选择城市 A,更新它的邻居城市(B 和 C)的最短路径。
- 从 A 到 B 距离是 10,更新 B 的距离为 10。
- 从 A 到 C 距离是 5,更新 C 的距离为 5。
城市A | 城市B | 城市C | 城市D |
0 | 10 | 5 | ∞ |
- 选择城市 C,更新它的邻居城市(B 和 D)的最短路径。
- 从 C 到 B 的距离是 2,加上 A 到 C 的距离 5,总共是 7,更新 B 的距离为 7。
- 从 C 到 D 的距离是 10,加上 A 到 C 的距离 5,总共是 15,更新 D 的距离为 15。
城市A | 城市B | 城市C | 城市D |
0 | 7 | 5 | 15 |
- 选择城市 B,更新它的邻居城市(D)的最短路径。
- 从 B 到 D 的距离是 20,加上 A 到 B 的距离 7,总共是 27,但是 D 的当前距离是 15,所以不更新。
城市A | 城市B | 城市C | 城市D |
0 | 7 | 5 | 15 |
- 选择城市 D,所有城市都已遍历完,最终得到最短路径15。
4. Dijkstra 算法的代码实现:
好了,听了这么多,大家是不是迫不及待想看看如何将这个算法转化成代码了呢?这里是一个简单的 Java 实现:
import java.util.*;
class Dijkstra {
public void findShortestPath(Graph graph, int source) {
int[] dist = new int[graph.size()];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[source] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>(Comparator.comparingInt(n -> n.distance));
pq.add(new Node(source, 0));
while (!pq.isEmpty()) {
Node node = pq.poll();
for (Edge edge : graph.getEdges(node)) {
if (dist[edge.to] > dist[node.id] + edge.weight) {
dist[edge.to] = dist[node.id] + edge.weight;
pq.add(new Node(edge.to, dist[edge.to]));
}
}
}
}
}
解释代码:
这段代码实现了 Dijkstra 算法,使用了 优先队列 来保证每次都选择最短路径。它通过更新每个节点的最短路径,最终输出从起点到其他所有节点的最短路径。
5. Dijkstra 与其他算法的对比
Dijkstra 算法虽然很强大,但它的应用场景是 单源最短路径。也就是说,它只关心从一个起点到其他所有点的最短路径。如果你需要计算 所有点对之间的最短路径,那么就需要使用 Floyd-Warshall 算法。
- Dijkstra 是单源最短路径,逐步更新距离。
- Floyd-Warshall 是所有点对之间的最短路径,一次性计算所有的路径。
6. 总结
今天我们学习了 Dijkstra 算法,它是一种高效的 单源最短路径算法。通过每次选择最短的路径,Dijkstra 算法帮助我们找到从一个点到其他所有点的最短路径,避免了冤枉路。
但这里有一个问题:我们知道 A 到 D 的最短距离是 15,假设起点是 A,终点是 D,但如何找到从 A 到 D 的具体路径呢?
这个问题我将在下一期为大家解答!敬请期待哦~