java实现迪杰斯特拉单源最短路径算法

用到的测试图

package algorithm;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;

/**
 *迪杰斯特拉算法 
 */
public class Dij {
	private int vertexNum;
	private int[][] martix;
	private boolean[] S;//已经求得的最短路径的顶点
	private boolean[] U;//未求的最短路径的顶点
	private Map<Integer,Integer> dist = new HashMap<>();//保存最短路径key代表终点 value代表当前的最短路径
	private int currentMidVertex;//当前的中间点,也就是每次产生的最短路径的那个点,该点之前不再S集合中
	private int startVertex = 0;
	public Dij(int[][] martix,int vertexNum) {
		this.martix = martix;
		this.vertexNum = vertexNum;
		S = new boolean[vertexNum];
		U = new boolean[vertexNum];
	}
	private void init(int startVertex) {
		//初始化S和U集合
		S[startVertex] = true;
		U[startVertex] = false;
		for(int i = 0; i<vertexNum; i++) {
			if(i!=startVertex)
				U[i] = true;
		}
		//初始化dist集合
		for(int i = 0;i<vertexNum;i++) {
			if(i!=startVertex) {
				if(martix[startVertex][i]!=0) {
					dist.put(i, martix[startVertex][i]);
				} else {
					dist.put(i, Integer.MAX_VALUE);
				}
			}
		}
		//初始化中间点
		this.currentMidVertex = startVertex;
	}
	public void dij(int startVertex) {//从哪个顶点出发
		this.startVertex = startVertex;
		init(startVertex);
		for(int i = 1;i<vertexNum;i++) {//循环顶点个数-1那么多次,每次加入一个顶点到S集合中
			currentMidVertex = shorestPath();//找到dist中当前最短路径的终点是哪一个
			if(currentMidVertex==Integer.MAX_VALUE) {
				continue;
			}
			S[currentMidVertex] = true;
			U[currentMidVertex] = false;
			//更新dist,使得其他路径经过currentMidVertex,如果路径值更小那么更新
			Set<Entry<Integer, Integer>> set = dist.entrySet();
			for (Entry<Integer, Integer> entry : set) {
				if(entry.getKey()!=currentMidVertex) {
					int newPath = dist.get(currentMidVertex);
					int b = path(currentMidVertex,entry.getKey());
					if(b!=0) {
						newPath+=b;
					} else {//没有可走的路径从currentMidVertex到终点
						continue;
					}
					if(newPath < entry.getValue()) {//如果更小就更新
						dist.put(entry.getKey(), newPath);
					}
				}
			}
		}
	}
	public void output() {
		Set<Entry<Integer, Integer>> set = dist.entrySet();
		for (Entry<Integer, Integer> entry : set) {
			if(entry.getValue() == Integer.MAX_VALUE) {
				System.out.println(startVertex+"->"+entry.getKey()+"的最短路径长度为:没有路径");
				continue;
			}
			System.out.println(startVertex+"->"+entry.getKey()+"的最短路径长度为:"+entry.getValue());
		}
	}
	private Integer path(int start, Integer destination) {//寻找一个路径起点是start,终点是destination
		if(martix[start][destination]!=0) {
			return martix[start][destination];
		}
		return 0;
	}
	//遍历dist返回当前的最短路径的终点是哪个
	public int shorestPath() {
		Set<Entry<Integer, Integer>> set = dist.entrySet();
		int minKey = Integer.MAX_VALUE;
		int minPath = Integer.MAX_VALUE;
		for (Entry<Integer, Integer> entry : set) {
			if(U[entry.getKey()]) {
				int key = entry.getKey();
				int value = entry.getValue();
				if(value < minPath) {
					minPath = value;
					minKey = key;
				}
			}
		}
		return minKey;
	}
	public static void main(String[] args) throws Exception {
		System.setIn(new FileInputStream("C:\\Users\\colin\\Desktop\\data2.txt"));
		Scanner scanner = new Scanner(System.in);
		//System.out.println("输入顶点个数:");
		int n = scanner.nextInt();
		//System.out.println("输入边的个数:");
		int m = scanner.nextInt();
		int[][] martix = new int[n][n];
		//System.out.println("输入每条边,每一行包含3个数,a,b,c:代表起点,终点,和权值");
		for(int i= 0;i<m;i++) {
			int a = scanner.nextInt();
			int b = scanner.nextInt();
			int c = scanner.nextInt();
			martix[a][b] = c;
		}
		Dij dij = new Dij(martix, n);
		dij.dij(1);
		dij.output();
	}
}
 
测试结果:
v1为起点
1->2的最短路径长度为:没有路径
1->3的最短路径长度为:10
1->4的最短路径长度为:50
1->5的最短路径长度为:30
1->6的最短路径长度为:60

v2为起点:
2->1的最短路径长度为:没有路径
2->3的最短路径长度为:5
2->4的最短路径长度为:55
2->5的最短路径长度为:没有路径
2->6的最短路径长度为:65

依次类推,可以任意选择起点求最短路径
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值