菜鳥筆記之資料結構(24)
資料結構與演算法—常用十種演算法8
宣告:以下是學的尚矽谷網課並結合網上資料所記的筆記。可能會有一些錯誤,發現了會修改。
迪傑斯特拉(Dijkstra)演算法
應用場景-最短路徑問題
演算法介紹
迪傑斯特拉(Dijkstra)演算法是典型最短路徑演算法,用於計算一個結點到其他結點的最短路徑。它的主要特點是以起始點為中心向外層擴充套件(廣度優先搜尋思想),知道擴充套件到終點為止。
演算法過程
圖解參考該文章 Dijkstra演算法(三)之 Java詳解
程式碼
import java.util.Arrays;
public class DijkstraAlgorithm {
public static void main(String[] args) {
char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
// 鄰接矩陣
int[][] matrix = new int[vertex.length][vertex.length];
final int N = 65535; // 表示不可連線
matrix[0] = new int[] { N, 5, 7, N, N, N, 2 };
matrix[1] = new int[] { 5, N, N, 9, N, N, 3 };
matrix[2] = new int[] { 7, N, N, N, 8, N, N };
matrix[3] = new int[] { N, 9, N, N, N, 4, N };
matrix[4] = new int[] { N, N, 8, N, N, 5, 4 };
matrix[5] = new int[] { N, N, N, 4, 5, N, 6 };
matrix[6] = new int[] { 2, 3, N, N, 4, 6, N };
// 建立Graph物件
Graph graph = new Graph(vertex, matrix);
graph.showGraph();
// 測試迪傑斯特拉
graph.dijkstra(6);
graph.showDijkstra();
}
}
class Graph {
private char[] vertex; // 頂點陣列
private int[][] matrix; // 鄰接矩陣
private VisitedVertex vv; // 已經訪問的頂點集合
// 構造器
public Graph(char[] vertex, int[][] matrix) {
this.vertex = vertex;
this.matrix = matrix;
}
//顯示結果
public void showDijkstra() {
vv.show();
}
// 顯示圖
public void showGraph() {
for (int[] link : matrix) {
System.out.println(Arrays.toString(link));
}
}
// dijkstra演算法
/**
* @param index 出發頂點對應的下標
*/
public void dijkstra(int index) {
vv = new VisitedVertex(vertex.length, index);
update(index); //更新index頂點到周圍頂點的距離和前驅頂點
for(int j = 1; j < vertex.length; j++) {
index = vv.updateArr(); //選擇並返回新的訪問結點
update(index); //更新index頂點到周圍頂點的距離和前驅頂點
}
}
// 更新index下標的頂點到周圍頂點的距離和周圍頂點的前驅頂點
private void update(int index) {
int len = 0;
// 遍歷鄰接矩陣的matrix[index]行
for (int j = 0; j < matrix[index].length; j++) {
// len含義是:出發頂點到index頂點的距離,加上從index頂點到j頂點距離的和
len = vv.getDis(index) + matrix[index][j];
// 如果j頂點沒有被訪問過,並且len小於出發頂點到j的距離就需要更新
if (!vv.in(j) && len < vv.getDis(j)) {
vv.updatePre(j, index); // 更新j頂點的前驅為index頂點
vv.updateDis(j, len); // 更新出發頂點到j頂點的距離
}
}
}
}
class VisitedVertex {
// 記錄各個頂點是否訪問過,1表示訪問過,0未訪問,會動態更新
public int[] already_arr;
// 每個下標對應的值為前一個頂點下標,會動態更新
public int[] pre_visited;
// 記錄出發頂點到其他所有頂點的距離,比如G為出發點,就會記錄G到其他頂點的距離,會動態更新,求的是最短距離就會存放到dis
public int[] dis;
// 構造器
/**
* @param length 頂點的個數
* @param index 出發頂點對應的下標,比如G頂點,下標就是6
*/
public VisitedVertex(int length, int index) {
this.already_arr = new int[length];
this.pre_visited = new int[length];
this.dis = new int[length];
// 初始化dis陣列
Arrays.fill(dis, 65535);
this.dis[index] = 0; // 設定出發頂點的訪問距離為0
this.already_arr[index] = 1; //設定出發頂點被訪問過
}
/**
* 功能: 判斷index頂點是否被訪問過
* @param index
* @return 如果訪問過返回true,否則返回false
*/
public boolean in(int index) {
return already_arr[index] == 1;
}
/**
* 功能:更新出發頂點到index頂點的距離
*
* @param index 更新頂點的下標
* @param len 更新的值為多少
*/
public void updateDis(int index, int len) {
dis[index] = len;
}
/**
* 功能:更新pre頂點的前驅結點為index
* @param pre
* @param index
*/
public void updatePre(int pre, int index) {
pre_visited[pre] = index;
}
// 功能:返回出發頂點到index頂點的距離
public int getDis(int index) {
return dis[index];
}
//繼續選擇並訪問新的訪問頂點,比如G完後,就是A作為新的訪問頂點(注意不是出發頂點)
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;
}
}
//更新index頂點被訪問過
already_arr[index] = 1;
return index;
}
//顯示最後的結果,即輸出三個陣列的情況
public void show() {
System.out.println("=============================");
//輸出already_arr
for(int i : already_arr) {
System.out.print(i + " ");
}
System.out.println();
//輸出pre_visited
for(int i : pre_visited) {
System.out.print(i + " ");
}
System.out.println();
//輸出dis
//為了好看,最後的最短距離
char[] vertex = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
int count = 0;
for(int i : dis) {
if(i != 65535) {
System.out.print(vertex[count] + "(" + i + ") ");
} else {
System.out.print("N");
}
count++;
}
System.out.println();
}
}
結果(G點到各點的最短距離):A(2) B(3) C(9) D(10) E(4) F(6) G(0) 。
--------------------------------------- 個人學習筆記----------------------------------------
相關文章
- 菜鳥筆記之PWN入門(1.0.0)前言筆記
- SQL菜鳥筆記之第六篇 資料的限制和排序 (下)SQL筆記排序
- SQL菜鳥筆記之第五篇 資料的限制和排序 (中)SQL筆記排序
- SQL菜鳥筆記之第四篇 資料的限制和排序 (上)SQL筆記排序
- 菜鳥筆記之計算機網路(4)筆記計算機網路
- 菜鳥也玩mysql之學習筆記篇MySql筆記
- SQL*Plus菜鳥筆記之第六篇SQL筆記
- SQL*Plus菜鳥筆記之第五篇SQL筆記
- SQL*Plus菜鳥筆記之第四篇SQL筆記
- SQL*Plus菜鳥筆記之第三篇SQL筆記
- SQL*Plus菜鳥筆記之第二篇SQL筆記
- 菜鳥的讀書筆記筆記
- 菜鳥筆記之pwn工具篇--Pwndbg基礎使用筆記
- 【菜鳥教程筆記】Python字串筆記Python字串
- MFC入門——菜鳥級筆記筆記
- 資料結構筆記資料結構筆記
- 【菜鳥筆記|機器學習】神經網路筆記機器學習神經網路
- 慶軍之菜鳥記錄-定期檢查並刪除資料
- 資料結構筆記——概述資料結構筆記
- 資料結構筆記——棧資料結構筆記
- 【菜鳥教程筆記】python基礎之元組的使用筆記Python
- Android菜鳥學習js筆記一AndroidJS筆記
- 鳥哥私房菜-基礎篇小筆記筆記
- 筆記:大話資料結構筆記資料結構
- 資料結構筆記——佇列資料結構筆記佇列
- 資料結構學習筆記資料結構筆記
- [做題筆記] 資料結構筆記資料結構
- 筆記-資料結構之 Hash(OC的粗略實現)筆記資料結構
- 鳥哥私房菜學習筆記(第零章)筆記
- linux-鳥哥私房菜學習筆記Linux筆記
- SQL菜鳥筆記之第九篇 SQL單行函式 (下)SQL筆記函式
- SQL菜鳥筆記之第八篇 SQL單行函式 (中)SQL筆記函式
- 資料結構學習筆記--棧資料結構筆記
- 資料結構學習筆記1資料結構筆記
- 線性表__資料結構筆記資料結構筆記
- 資料結構筆記——演算法資料結構筆記演算法
- SQL菜鳥筆記之第七篇 SQL單行函式 (上)SQL筆記函式
- 菜鳥學SSH(十一)——Hibernate之SchemaExport+配置檔案生成表結構Export