Dijkstra算法如同一位智慧的导航员:
整个过程就像在迷雾中点亮一盏盏路灯,逐步照亮整个地图的最短路径。
import java.util.*;
class Graph {
private int V;
private List<List<Node>> adj;
class Node implements Comparable<Node> {
int vertex;
int distance;
Node(int vertex, int distance) {
this.vertex = vertex;
this.distance = distance;
}
@Override
public int compareTo(Node other) {
return Integer.compare(this.distance, other.distance);
}
}
public Graph(int V) {
this.V = V;
adj = new ArrayList<>();
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
}
public void addEdge(int src, int dest, int weight) {
adj.get(src).add(new Node(dest, weight));
// 无向图需添加反向边:adj.get(dest).add(new Node(src, weight));
}
public int[] dijkstra(int src) {
int[] dist = new int[V];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[src] = 0;
PriorityQueue<Node> pq = new PriorityQueue<>();
pq.add(new Node(src, 0));
boolean[] visited = new boolean[V];
while (!pq.isEmpty()) {
Node node = pq.poll();
int u = node.vertex;
if (visited[u]) continue;
visited[u] = true;
for (Node neighbor : adj.get(u)) {
int v = neighbor.vertex;
int weight = neighbor.distance;
if (dist[v] > dist[u] + weight) {
dist[v] = dist[u] + weight;
pq.add(new Node(v, dist[v]));
}
}
}
return dist;
}
public static void main(String[] args) {
Graph g = new Graph(5);
g.addEdge(0, 1, 4);
g.addEdge(0, 2, 1);
g.addEdge(2, 1, 2);
g.addEdge(2, 3, 5);
g.addEdge(1, 3, 1);
g.addEdge(3, 4, 3);
int[] dist = g.dijkstra(0);
System.out.println("从0出发到各顶点的最短距离:");
for (int i = 0; i < dist.length; i++) {
System.out.println(i + " : " + dist[i]);
}
}
}
指标 | 数值 | 说明 |
---|---|---|
时间复杂度 | O((V+E) log V) | 使用优先队列优化(V:顶点,E:边) |
空间复杂度 | O(V+E) | 存储邻接表和优先队列 |
最佳场景 | 无负权边的加权图 | 适用于大多数现实场景 |
算法特性:
典型案例:
新手必练:
// 邻接矩阵实现示例
public void dijkstraMatrix(int[][] graph, int src) {
int V = graph.length;
int[] dist = new int[V];
Arrays.fill(dist, Integer.MAX_VALUE);
dist[src] = 0;
boolean[] visited = new boolean[V];
for (int count = 0; count < V-1; count++) {
int u = minDistance(dist, visited);
visited[u] = true;
for (int v = 0; v < V; v++) {
if (!visited[v] && graph[u][v] != 0 &&
dist[u] != Integer.MAX_VALUE &&
dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}
}
高手进阶:
// 双向Dijkstra核心逻辑
public int bidirectionalDijkstra(Graph graph, int src, int dest) {
// 初始化前向和后向搜索
PriorityQueue<Node> frontQueue = new PriorityQueue<>();
PriorityQueue<Node> backQueue = new PriorityQueue<>();
int[] frontDist = new int[V];
int[] backDist = new int[V];
Arrays.fill(frontDist, Integer.MAX_VALUE);
Arrays.fill(backDist, Integer.MAX_VALUE);
frontDist[src] = 0;
backDist[dest] = 0;
while (!frontQueue.isEmpty() && !backQueue.isEmpty()) {
// 交替执行前向和后向搜索
expandFrontier(frontQueue, frontDist);
expandFrontier(backQueue, backDist);
// 检查相遇节点
int meetNode = checkMeetingPoint(frontDist, backDist);
if (meetNode != -1) {
return frontDist[meetNode] + backDist[meetNode];
}
}
return -1; // 无通路
}
Dijkstra算法教会我们:
当你能在百万级节点的社交网络中快速找到人际关系的最短路径时,说明真正掌握了算法的精髓——这不仅需要代码实现能力,更需要将数学思维转化为解决实际问题的智慧。记住:最优路径的探索永无止境,正如算法优化的道路永远向创新者敞开。