必会算法总结(5) - 弗洛伊德算法
弗洛伊德算法又是一个图论的算法,可能有小伙伴会问,会这么多图论的算法有用吗?可以说这对于校招进大厂的小伙伴是特别重要的,而且图相对于其它的数据结构是比较复杂的,现在的笔试动不动就是一道基于图去实现的题,可以说图论算法成了进大厂的第一步,所以我们必须特别重视图论算法的设计与实现。
回到正题,上一篇我们讲解的迪杰斯特拉算法广泛适用于单源最短路径问题,而弗洛伊德算法则更广泛的适用于多源最短路径问题,因为它用到了动态规划的思路去求解,所以避免了重复计算。各位要区分清除一个算法所解决的问题域。写这篇博客的时候我看大多数人都是用邻接矩阵去实现弗洛伊德算法,那么这里我给出基于邻接表的实现方式。
算法核心
弗洛伊德算法的核心在于二维矩阵shortest,它存储两个节点之间的最小距离。有了这个shortest矩阵,若shortest[i][j] > shortest[i][k] + shortest[k][j],则需要更新shortest[i][j]
图的存储结构
这里我选用图的邻接表存储形式:
-
Node类
public class Node { int value; Map<Node, Integer> neighbors; public Node() { } public Node(int value) { this.value = value; } public Node(int value, Map<Node, Integer> neighbors) { this.value = value; this.neighbors = neighbors; } }
-
Graph类
public class Graph { List<Node> nodes; public Graph() { } public Graph(List<Node> nodes) { this.nodes = nodes; } }
算法核心
public Map<Node, Map<Node, Integer>> shortestPath(Graph graph) {
// 创建最短距离矩阵:shortest
Map<Node, Map<Node, Integer>> shortest = new TreeMap<>(