实现一个最短路径算法,并分析其时间复杂度和空间复杂度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 import java.util.*;public class Graph { private Map<Integer, List<Node>> adjacencyList; public Graph (int vertices) { adjacencyList = new HashMap <>(); for (int i = 1 ; i <= vertices; i++) { adjacencyList.put(i, new ArrayList <>()); } } public void addEdge (int source, int destination, int weight) { Node node = new Node (destination, weight); adjacencyList.get(source).add(node); node = new Node (source, weight); adjacencyList.get(destination).add(node); } public void dijkstra (int sourceVertex) { PriorityQueue<Node> priorityQueue = new PriorityQueue <>(adjacencyList.size(), Comparator.comparingInt(o -> o.cost)); int [] distance = new int [adjacencyList.size()]; boolean [] visited = new boolean [adjacencyList.size()]; distance[sourceVertex - 1 ] = 0 ; priorityQueue.add(new Node (sourceVertex, 0 )); while (!priorityQueue.isEmpty()) { int currentVertex = priorityQueue.remove().vertex; if (visited[currentVertex - 1 ]) { continue ; } visited[currentVertex - 1 ] = true ; List<Node> adjacentNodes = adjacencyList.get(currentVertex); for (Node adjacentNode : adjacentNodes) { int adjacentVertex = adjacentNode.vertex; int edgeWeight = adjacentNode.cost; if (!visited[adjacentVertex - 1 ]) { int newCost = distance[currentVertex - 1 ] + edgeWeight; if (newCost < distance[adjacentVertex - 1 ]) { distance[adjacentVertex - 1 ] = newCost; priorityQueue.add(new Node (adjacentVertex, newCost)); } } } } for (int i = 0 ; i < distance.length; ++i) { System.out.println("Distance from " + sourceVertex + " to " + (i + 1 ) + " is " + distance[i]); } } private static class Node { int vertex; int cost; public Node (int vertex, int cost) { this .vertex = vertex; this .cost = cost; } } }
最短路径算法是用于找到图中两个节点之间的最短路径的一组算法。其中,Dijkstra's algorithm
和Bellman-Ford algorithm是最常用的两种算法。其时间复杂度和空间复杂度如下:
时间复杂度 :O(ElogV)
,其中E为边数,V为节点数。
空间复杂度 :O(V)
,其中V为节点数。
时间复杂度:O(VE),其中E为边数,V为节点数。
空间复杂度:O(V),其中V为节点数。
需要注意的是,Dijkstra’s algorithm适用于有向无环图(DAG)或非负权重图,而Bellman-Ford algorithm则适用于带有负权重的图。
验证:
1 2 3 4 5 6 7 8 9 10 11 12 public static void main (String[] args) { Graph graph = new Graph (5 ); graph.addEdge(1 , 2 , 2 ); graph.addEdge(1 , 4 , 1 ); graph.addEdge(2 , 3 , 3 ); graph.addEdge(3 , 4 , 4 ); graph.addEdge(4 , 5 , 3 ); graph.addEdge(3 , 5 , 2 ); graph.dijkstra(1 ); }