迪克斯特拉算法主要特色是以起始點爲中心向外層層擴展,直到擴展到終點爲止,就像剝洋蔥同樣,因此它也屬於廣度優先搜索。java
老哥們本身找吧,網上沒找到一篇能讓我徹底滿意的證實node
public class Dijkstra { public static final int INF = 65535; public static final String RIGHT_ARROW = "-->"; public static final String LEFT_ARROW = "<--"; public static void main(String[] args) { getShortestDistance(new int[][]{ {0, INF, 10, INF, 30, 100}, {INF, 0, 5, INF, INF, INF}, {INF, INF, 0, 50, INF, INF}, {INF, INF, INF, 0, INF, 10}, {INF, INF, INF, 20, 0, 60}, {INF, INF, INF, INF, INF, 0} }, 0); } private static void getShortestDistance(int[][] matrix, int start) { boolean[] visited = new boolean[matrix.length]; // 節點是否已被訪問 int[] distance = new int[matrix.length]; // 距離數組 int[] pre = new int[matrix.length]; // 前驅數組,用於記錄路徑信息 // 初始化距離數組、前驅數組,訪問數組 for (int j = 0; j < matrix[start].length; j++) { distance[j] = matrix[start][j]; if (distance[j] == INF) { pre[j] = -1; } else { pre[j] = start; } visited[j] = false; } // 初始節點設置爲已訪問 visited[start] = true; int k = start; while (k != -1) { visited[k] = true; for (int j = 0; j < matrix[k].length; j++) { if (matrix[k][j] + distance[k] < distance[j]) { distance[j] = matrix[k][j] + distance[k]; pre[j] = k; } } // 獲取下一個距離起始節點最近的未被訪問的節點 k = getNextNodeIndex(visited, distance); } // 打印最短距離和路徑 printShortestPath(distance, pre, start); } private static void printShortestPath(int[] distance, int[] pre, int start) { for (int i = 0; i < distance.length; i++) { StringBuilder sb = new StringBuilder(); sb.append(getNodeName(start)); sb.append(RIGHT_ARROW); sb.append(getNodeName(i)); if (distance[i] < INF) { sb.append("最短距離:"); sb.append(distance[i]); sb.append("\t"); } else { sb.append("不通"); continue; } sb.append("最短路徑"); sb.append(getNodeName(i)); sb.append(LEFT_ARROW); int j = i; do { j = pre[j]; sb.append(getNodeName(j)); sb.append(LEFT_ARROW); } while (pre[j] != -1 && j != start); System.out.println(sb.substring(0, sb.lastIndexOf(LEFT_ARROW))); } } private static int getNextNodeIndex(boolean[] visited, int[] distance) { int min = INF; int k = -1; for (int i = 0; i < distance.length; i++) { if (distance[i] < min && !visited[i]) { min = distance[i]; k = i; } } return k; } private static String getNodeName(int nodeIdx) { return "v" + (nodeIdx + 1); } 結果打印: v1-->v1最短距離:0 最短路徑v1<--v1 v1-->v3最短距離:10 最短路徑v3<--v1 v1-->v4最短距離:50 最短路徑v4<--v5<--v1 v1-->v5最短距離:30 最短路徑v5<--v1 v1-->v6最短距離:60 最短路徑v6<--v4<--v5<--v1
我另外想了一種方法來實現尋找最短路徑,相似迪克斯特拉算法,只不過將廣度優先搜索變爲深度優先搜索算法
public class DetectShotestDistance { public static final int INF = 65535; public static final String RIGHT_ARROW = "-->"; public static final String LEFT_ARROW = "<--"; public static void main(String[] args) { getShortestDistance(new int[][]{ {0, INF, 10, INF, 30, 100}, {INF, 0, 5, INF, INF, INF}, {INF, INF, 0, 50, INF, INF}, {INF, INF, INF, 0, INF, 10}, {INF, INF, INF, 20, 0, 60}, {INF, INF, INF, INF, INF, 0} }, 0); } private static void getShortestDistance(int[][] matrix, int start) { Set visited = new HashSet<>(); int[] distance = new int[matrix.length]; int[] pre = new int[matrix.length]; // 初始化距離數組和路徑數組 for (int j = 0; j < matrix[start].length; j++) { distance[j] = matrix[start][j]; if (distance[j] == INF) { pre[j] = -1; } else { pre[j] = start; } } int curIdx = start; visited.add(curIdx); int nextIdx = getNextNodeIndex(start, matrix, visited, distance, pre); while (nextIdx != -1) { visited.add(nextIdx); if (matrix[curIdx][nextIdx] + distance[curIdx] < distance[nextIdx]) { distance[nextIdx] = matrix[curIdx][nextIdx] + distance[curIdx]; } curIdx = nextIdx; nextIdx = getNextNodeIndex(nextIdx, matrix, visited, distance, pre); } for (int i = 0; i < distance.length; i++) { StringBuilder sb = new StringBuilder(); sb.append(getNodeName(start)); sb.append(RIGHT_ARROW); sb.append(getNodeName(i)); if (distance[i] < INF) { sb.append("最短距離:"); sb.append(distance[i]); sb.append("\t"); } else { sb.append("不通"); continue; } sb.append("最短路徑"); sb.append(getNodeName(i)); sb.append(LEFT_ARROW); int j = i; do { j = pre[j]; sb.append(getNodeName(j)); sb.append(LEFT_ARROW); } while (pre[j] != -1 && j != start); System.out.println(sb.substring(0, sb.lastIndexOf(LEFT_ARROW))); } } private static int getNextNodeIndex(int curIdx, int[][] matrix, Set visited, int[] distance, int[] pre) { int min = INF; int minIdx = -1; for (int j = 0; j < matrix[curIdx].length; j++) { if (matrix[curIdx][j] < min && !visited.contains(j)) { min = matrix[curIdx][j]; minIdx = j; pre[minIdx] = curIdx; } } if (minIdx == -1) { for (int j = 0; j < distance.length; j++) { if (distance[j] != INF && !visited.contains(j)) { return j; } } } return minIdx; } private static String getNodeName(int nodeIdx) { return "v" + (nodeIdx + 1); } 結果打印: v1-->v1最短距離:0 最短路徑v1<--v1 v1-->v3最短距離:10 最短路徑v3<--v1 v1-->v4最短距離:50 最短路徑v4<--v5<--v1 v1-->v5最短距離:30 最短路徑v5<--v1 v1-->v6最短距離:60 最短路徑v6<--v4<--v5<--v1