概述
迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。迪杰斯特拉算法采用的是贪心策略,将Graph中的节点集分为最短路径计算完成的节点集S和未计算完成的节点集T,每次将从T中挑选V0->Vt最小的节点Vt加入S,并更新V0经由Vt到T中剩余节点的更短距离,直到T中的节点全部加入S中,它贪心就贪心在每次都选择一个距离源点最近的节点加入最短路径节点集合。迪杰斯特拉算法只支持非负权图,它计算的是单源最短路径,即单个源点到剩余节点的最短路径,时间复杂度为O(n²)。
1.
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| |
| |
| |
| |
| public class ShortestPathDijkstra { |
| |
| |
| |
| private int[][] matrix; |
| |
| |
| |
| private int MAX_WEIGHT = Integer.MAX_VALUE; |
| |
| |
| |
| private String[] vertexes; |
| |
| |
| |
| |
| private void createGraph2(int index) { |
| matrix = new int[index][index]; |
| vertexes = new String[index]; |
| |
| int[] v0 = {0, 1, 5, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT}; |
| int[] v1 = {1, 0, 3, 7, 5, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT}; |
| int[] v2 = {5, 3, 0, MAX_WEIGHT, 1, 7, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT}; |
| int[] v3 = {MAX_WEIGHT, 7, MAX_WEIGHT, 0, 2, MAX_WEIGHT, 3, MAX_WEIGHT, MAX_WEIGHT}; |
| int[] v4 = {MAX_WEIGHT, 5, 1, 2, 0, 3, 6, 9, MAX_WEIGHT}; |
| int[] v5 = {MAX_WEIGHT, MAX_WEIGHT, 7, MAX_WEIGHT, 3, 0, MAX_WEIGHT, 5, MAX_WEIGHT}; |
| int[] v6 = {MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 3, 6, MAX_WEIGHT, 0, 2, 7}; |
| int[] v7 = {MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 9, 5, 2, 0, 4}; |
| int[] v8 = {MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, MAX_WEIGHT, 7, 4, 0}; |
| matrix[0] = v0; |
| matrix[1] = v1; |
| matrix[2] = v2; |
| matrix[3] = v3; |
| matrix[4] = v4; |
| matrix[5] = v5; |
| matrix[6] = v6; |
| matrix[7] = v7; |
| matrix[8] = v8; |
| |
| vertexes[0] = "v0"; |
| vertexes[1] = "v1"; |
| vertexes[2] = "v2"; |
| vertexes[3] = "v3"; |
| vertexes[4] = "v4"; |
| vertexes[5] = "v5"; |
| vertexes[6] = "v6"; |
| vertexes[7] = "v7"; |
| vertexes[8] = "v8"; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public void dijkstra(int vs) { |
| |
| boolean[] flag = new boolean[vertexes.length]; |
| |
| int[] U = new int[vertexes.length]; |
| |
| int[] prev = new int[vertexes.length]; |
| |
| String[] S = new String[vertexes.length]; |
| |
| |
| for (int i = 0; i < vertexes.length; i++) { |
| flag[i] = false; |
| U[i] = matrix[vs][i]; |
| |
| prev[i] = 0; |
| } |
| |
| |
| flag[vs] = true; |
| U[vs] = 0; |
| |
| S[0] = vertexes[vs]; |
| |
| |
| |
| |
| int k = 0; |
| for (int i = 1; i < vertexes.length; i++) { |
| |
| |
| |
| |
| int min = MAX_WEIGHT; |
| for (int j = 0; j < vertexes.length; j++) { |
| if (flag[j] == false && U[j] < min) { |
| min = U[j]; |
| k = j; |
| } |
| } |
| |
| |
| S[i] = vertexes[k]; |
| |
| |
| |
| |
| |
| |
| flag[k] = true; |
| |
| |
| |
| for (int j = 0; j < vertexes.length; j++) { |
| |
| int tmp = (matrix[k][j] == MAX_WEIGHT ? MAX_WEIGHT : (min + matrix[k][j])); |
| if (flag[j] == false && (tmp < U[j])) { |
| U[j] = tmp; |
| |
| prev[j] = k; |
| } |
| } |
| |
| } |
| |
| |
| |
| System.out.println("起始顶点:" + vertexes[vs]); |
| for (int i = 0; i < vertexes.length; i++) { |
| System.out.print("最短路径(" + vertexes[vs] + "," + vertexes[i] + "):" + U[i] + " "); |
| |
| List<String> path = new ArrayList<>(); |
| int j = i; |
| while (true) { |
| path.add(vertexes[j]); |
| |
| if (j == 0) |
| break; |
| |
| j = prev[j]; |
| } |
| |
| for (int x = path.size() - 1; x >= 0; x--) { |
| if (x == 0) { |
| System.out.println(path.get(x)); |
| } else { |
| System.out.print(path.get(x) + "->"); |
| } |
| } |
| |
| } |
| |
| System.out.println("顶点放入S中的顺序:"); |
| for (int i = 0; i < vertexes.length; i++) { |
| |
| System.out.print(S[i]); |
| |
| if (i != vertexes.length - 1) |
| System.out.print("-->"); |
| } |
| |
| } |
| |
| public static void main(String[] args) { |
| ShortestPathDijkstra dij = new ShortestPathDijkstra(); |
| |
| dij.createGraph2(9); |
| dij.dijkstra(0); |
| } |
| |
| } |
2.
| |
| import java.util.Arrays; |
| |
| |
| |
| |
| |
| public class DijkstraAlgorithm { |
| public static void main(String[] args) { |
| char [] vertex = {'A','B','C','D','E','F','G'}; |
| final int N = 65535; |
| int [][] matrix = { |
| {N,5,7,N,N,N,2}, |
| {5,N,N,9,N,N,3}, |
| {7,N,N,N,8,N,N}, |
| {N,9,N,N,N,4,N}, |
| {N,N,8,N,N,5,4}, |
| {N,N,N,4,5,N,6}, |
| {2,3,N,N,4,6,N} |
| }; |
| |
| |
| DGraph dGraph = new DGraph(vertex, matrix); |
| dGraph.showDGraph(); |
| |
| dGraph.djs(6); |
| dGraph.show(); |
| |
| } |
| } |
| |
| class DGraph{ |
| char [] vertex; |
| int [][] matrix; |
| VisitedVertex vv; |
| |
| |
| public DGraph(char [] vertex, int [][] matrix){ |
| this.vertex = vertex; |
| this.matrix = matrix; |
| } |
| |
| |
| public void showDGraph(){ |
| for(int [] link : matrix){ |
| System.out.println(Arrays.toString(link)); |
| } |
| } |
| |
| |
| public void djs(int index){ |
| vv = new VisitedVertex(vertex.length, index); |
| update(index); |
| |
| for(int j = 1; j < vertex.length; j++){ |
| index = vv.updateArr(); |
| update(index); |
| } |
| } |
| |
| |
| public void update(int index){ |
| int len = 0; |
| for(int j = 0; j < matrix[index].length; j++){ |
| len = vv.getDis(index) + matrix[index][j]; |
| if(!vv.in(j) && len < vv.getDis(j)){ |
| vv.updatePre(j,index); |
| vv.updateDis(j,len); |
| } |
| } |
| } |
| |
| |
| public void show(){ |
| vv.show(); |
| } |
| |
| } |
| |
| class VisitedVertex{ |
| |
| public int [] already_arr; |
| |
| |
| public int [] pre_visited; |
| |
| |
| public int [] dis; |
| |
| |
| |
| public VisitedVertex(int length, int index){ |
| this.already_arr = new int[length]; |
| this.pre_visited = new int[length]; |
| this.dis = new int[length]; |
| Arrays.fill(dis,65535); |
| this.already_arr[index] = 1; |
| this.dis[index] = 0; |
| } |
| |
| |
| public boolean in(int index){ |
| return already_arr[index] == 1; |
| } |
| |
| |
| public void updateDis(int index, int len){ |
| dis[index] = len; |
| } |
| |
| |
| public void updatePre(int pre, int index){ |
| pre_visited[pre] = index; |
| } |
| |
| |
| public int getDis(int index){ |
| return dis[index]; |
| } |
| |
| |
| public int updateArr(){ |
| int min = 65535; |
| int index = 0; |
| for(int i = 0; i < already_arr.length; i++){ |
| if(already_arr[i] == 0 && dis[i] < min){ |
| min = dis[i]; |
| index = i; |
| } |
| } |
| already_arr[index] = 1; |
| return index; |
| } |
| |
| |
| public void show(){ |
| System.out.println("================"); |
| for(int i : already_arr){ |
| System.out.print(i + " "); |
| } |
| |
| System.out.println(); |
| |
| for(int i : pre_visited){ |
| System.out.print(i + " "); |
| } |
| |
| System.out.println(); |
| |
| for(int i : dis){ |
| System.out.print(i + " "); |
| } |
| char [] vertex = {'A','B','C','D','E','F','G'}; |
| System.out.println(); |
| System.out.println("当前开始为"+vertex[6]); |
| int count = 0; |
| for(int i:dis ){ |
| if (i!=65535){ |
| System.out.print(vertex[count]+"("+i+")"); |
| }else { |
| System.out.println("N "); |
| } |
| count++; |
| } |
| System.out.println(); |
| } |
| |
| } |
| |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南