迪杰斯特拉算法
迪杰斯特拉算法(Dijkstra's algorithm)是一种用于解决加权图中单源最短路径问题的贪心算法。该算法的主要思想是从起点开始,按照节点到起点的距离递增的顺序,逐一确定每个节点的最短路径,直到到达终点为止。
基本步骤:
- 初始化:将起点到各个节点的距离都初始化为无穷大,将起点到自身的距离初始化为0。
- 从起点开始遍历:每次选择当前距离起点最近的未访问节点,将其加入已访问节点集合,并更新起点到其它未访问节点的距离。
- 重复上一步,直到所有节点都被加入已访问节点 集合或者到达终点。
迪杰斯特拉算法的优点是能够找到单源最短路径,且能够处理有向图和带有负权边的图(前提是无负环)。缺点是时间复杂度较高,为O(n^2),且需要保证所有边的权值为非负整数。
代码实现
import java.util.*;
public class DijkstraAlgorithm {
private static final int MAX = 10000; // 无穷大
private static int[][] graph = new int[MAX][MAX]; // 图的邻接矩阵
private static int[] dist = new int[MAX]; // 最短距离
private static boolean[] visited = new boolean[MAX]; // 记录节点是否已经访问过
// Dijkstra算法函数
private static void dijkstra(int start) {
Arrays.fill(visited, false); // 将visited数组初始化为false
Arrays.fill(dist, MAX); // 将dist数组初始化为无穷大
dist[start] = 0; // 起始节点的最短距离为0
for (int i = 0; i < graph.length; i++) {
int u = -1;
int minDist = MAX;
// 找到最短距离的节点u
for (int j = 0; j < graph.length; j++) {
if (!visited[j] && dist[j] < minDist) {
u = j;
minDist = dist[j];
}
}
// 如果不存在最短距离的节点u,算法结束
if (u == -1) {
break;
}
visited[u] = true; // 标记节点u为已访问
// 更新节点u的邻居节点的最短距离
for (int v = 0; v < graph.length; v++) {
if (!visited[v] && graph[u][v] != 0) {
int newDist = dist[u] + graph[u][v];
if (newDist < dist[v]) {
dist[v] = newDist;
}
}
}
}
}
public static void main(String[] args) {
// 初始化图的邻接矩阵
for (int i = 0; i < MAX; i++) {
Arrays.fill(graph[i], 0);
}
graph[0][1] = 10;
graph[0][2] = 3;
graph[1][2] = 1;
graph[1][3] = 2;
graph[2][1] = 4;
graph[2][3] = 8;
graph[2][4] = 2;
graph[3][4] = 7;
graph[4][3] = 9;
dijkstra(0); // 从节点0开始执行Dijkstra算法
// 输出最短距离
for (int i = 0; i < dist.length; i++) {
System.out.println("到节点" + i + "的最短距离为:" + dist[i]);
}
}
}
需要注意Dijkstra算法是一种最短路径算法,用于在加权图中查找源顶点和所有其他顶点之间的最短路径。在编写Dijkstra算法时需要注意以下几点:
- Dijkstra算法仅适用于具有非负边权的图。
- 该算法维护了一组已访问的顶点和一组未访问的顶点。
- 该算法使用优先队列选择距离源顶点最近的顶点。
- 如果当前顶点的未访问邻居的距离小于其当前距离,则该算法会更新每个未访问邻居的距离。
- 当所有顶点都被访问或未访问顶点中最小距离为无穷大时,该算法终止。