Dijkstra算法,求最短路径问题

解析过程:

    使用两个S[ ]和dis[ ]两个数组,S[i]表示i节点是否已经找到最短路径,dis[i]表示定点距离i的最短路程。

    例如:

     假设已知定点为0,求各个节点到0的距离。

   

    构建出一个表格方便观察过程:

    第一排代表节点

    第二排是判断是否已经找到最短路径

    第三排是定点到任意点的距离

   

  0这个点离自己距离是0,且已经是最短路径,变为true

   

   0的出度有1和2,且距离分别是1和12,再在所有false中找到距离最短的,则就可确定离0最近的是1,变为true

   

   同理,1的出度有2和3,离0的距离分别是1+9和1+3,因为到2的距离为10<12,所有更新为10,且3的距离最短,变为true

   

   同理,3的出度有2,4,5,例如到2的情况:0-1-3-2的路程为8<10,更新为8。4和5同理。

   

   接下来情况和前面类似

   

   

   这样就求得dis数组为0,1,8,4,13,17,分别表示距离0的距离

代码实现:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		//邻接矩阵
  		int[][] map = {
  				{0,1,12,0,0,0},
  				{0,0,9,3,0,0},
  				{0,0,0,0,5,0},
  				{0,0,4,0,13,15},
  				{0,0,0,0,0,4},
  				{0,0,0,0,0,0}};
  		int[] dis = new int[map[0].length];//任意一点到定点的距离数组
  		boolean[] S = new boolean[map[0].length];	//是否寻找到最短路径
  		for (int i = 0; i < dis.length; i++) {
  			S[i] = false;
			dis[i] = Integer.MAX_VALUE;
		}
  		getdis(dis,S,map,0);
	}
	/**
	 * 
	 * @param dis	dis数组
	 * @param S		S数组
	 * @param map	邻接矩阵
	 * @param first	定点
	 */
	private static void getdis(int[] dis, boolean[] S, int[][] map, int first) {
		dis[first]=0;//到自己的距离为0
		S[first]=true;//自己已经是最短
		int n = map[0].length;//节点个数
		for (int i = 0; i < n; i++) {
			if(map[first][i]!=0){
				dis[i]=map[first][i];//从自己出发到能到点的距离
			}
		}
		for (int i = 1; i < n; i++) {
			int min = Integer.MAX_VALUE;
			int flag=-1;
			//找到未被置为true的最短点
			for (int j = 0; j < n; j++) {
				if(!S[j] && dis[j]<min){
					min = dis[j];
					flag=j;
				}
			}
			if(flag!=-1) {
				S[flag]=true;
				for (int j = 0; j < n; j++) {
					if(!S[j] && map[flag][j]!=0 && map[flag][j]+dis[flag] < dis[j]){
						dis[j]= map[flag][j]+dis[flag];//更新
					}
				}
			}
		}
		for (int i = 0; i < dis.length; i++) {
			if(dis[i]==Integer.MAX_VALUE) System.out.print("无法到达 ");
			else System.out.print(dis[i]+" ");
		}
	}
}

输出结果:

0 1 8 4 13 17 

如果改变定点为1,则输出结果变为:

无法到达 0 7 3 12 16 

注意这个算法不能运用到边的权值存在负值的情况。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值