尚硅谷Java數據結構學習記錄37-迪傑斯特拉算法

!!!!又稱銀行家算法,超經典超難的!!!!

迪傑斯特拉是找一個結點到其它所有結點的最短路徑 用文字描述有點難

一開始目標結點只能到達臨近的點

此時選擇路徑最小的點

更新目標點到其它點的距離(因爲可以經過最小的點到達其它點)

在新的距離中繼續找最小點

package Algorithm;

import java.util.Arrays;

public class Dijkstra {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		char[] vertexs = {'A','B','C','D','E','F','G'};
		int[][] martex = new int[vertexs.length][vertexs.length];
		final int N = 65535;
		martex[0] = new int[] {N,5,7,N,N,N,2};
		martex[1] = new int[] {5,N,N,9,N,N,3};

		martex[2] = new int[] {7,N,N,N,8,N,N};

		martex[3] = new int[] {N,9,N,N,N,4,N};

		martex[4] = new int[] {N,N,8,N,N,5,4};
		martex[5] = new int[] {N,N,N,4,5,N,6};
		martex[6] = new int[] {2,3,N,N,4,6,N};

		Graph graph = new Graph(vertexs,martex);
		graph.showGraph();
		graph.dsj(6);
		graph.showDijkstra();
	}
	
	
	static class VisitedVertex{
		//記錄各個頂點是否被訪問 1表示訪問0 表示未訪問
		public int[] already_array;
		//給個下標對應的值爲前一個原點下標,會動態更新
		public int[] pre_visited;
		//記錄出發頂點到其它所有頂點的距離
		public int[] dis;
		
		public VisitedVertex(int length,int index) {
			this.already_array = new int[length];
			//index表示出發頂點對應的下標
			this.pre_visited = new int[length];
			this.dis = new int[length];
			//初始化dis
			Arrays.fill(dis, 65535);
			this.already_array[index] = 1; //設置出發頂點被訪問過
			this.dis[index] = 0;
		}
		
		//判斷Index是否被訪問古過 如果訪問過返回true
		public boolean in(int index) {
			return already_array[index] == 1;
		}

		public void updateDis(int index,int len) {
			//更新出髮結點到index結點的距離
			dis[index] = len;
		}
		

		
		//更新結點Pre的前驅結點爲index
		public void updatePre(int pre,int index) {
			pre_visited[pre] = index;
		}
		
		public void show() {
			//輸出數組
			System.out.println(Arrays.toString(already_array));
			System.out.println(Arrays.toString(pre_visited));
			System.out.println(Arrays.toString(dis));


		}
		
		//返回出發結點到index結點的距離
		public int getDis(int index) {
			return dis[index];
		}
		
		
		public int updateArr() {
			int min = 65535,index = 0;
			for(int i = 0; i < already_array.length; i++) {
				if(already_array[i] == 0 && dis[i] < min) {
					min = dis[i];
					index = i;
					
				}

			}
			already_array[index] = 1;

			return index;
		}
	}
	static class Graph{
		private char[] vertex;
		private int[][] matrix;
		private VisitedVertex vv;//已經訪問的頂點的集合
		//構造器

		public void dsj(int index) {
			
			//重點注意這一句 我寫的VisitedVertex vv = new VisitedVertex(vertex.length,index);然後報錯 是因爲此時的vv被重新創建必然爲null
 
			vv = new VisitedVertex(vertex.length,index);
			update(index);
			for(int i = 1; i < vertex.length; i++) {
				index = vv.updateArr();
				update(index);

			}

		}
		
		//更新Index下標
		private void update(int index) {
			int len = 0;
			//根據遍歷鄰接矩陣的 matrix[index]
			for(int i = 0; i < matrix[index].length;i++) {
				//出發結點到index的距離+index到結點i的距離
				len = vv.getDis(index) + matrix[i][index];
				//如果i結點沒有訪問過並且Len要小於出發點到I的距離,則將距離替換爲vv,將index的前驅爲i
				if(!vv.in(i) && len < vv.getDis(i)) {
					vv.updatePre(i, index);
					vv.updateDis(i, len);
				}
			}
		}
		
		public Graph(char[] vertex, int[][] matrix) {
			super();
			this.vertex = vertex;
			this.matrix = matrix;
		}
		
		//顯示圖
		public void showGraph() {
			for(int[] link : matrix) {
				System.out.println(Arrays.toString(link));
			}
		}
		
		
		public void showDijkstra() {
			vv.show();
		}
		
		
	}

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章