单源最短路径——迪杰斯特拉(java实现 带测试点 完整代码)

   迪杰斯特拉是对顶点进行操作,适合稠密图,大致思想就是选定一个源点,dis数组记录的就是这个源头到各个顶点间的距离,还没进行迪杰斯特拉之前,dis其实就是邻接矩阵中的其中一行,然后进行迪杰斯特拉,先找到离这个源头最近的顶点k,将其标记,并且以这个点为中间点,看有没有别的顶点通过这个顶点k到源点的距离比dis记录的要小,如果有就更新。
   关于创建邻接矩阵的部分这里就不多说了,前面我写的博客有讲解。


import java.util.Arrays;
import java.util.Scanner;

public class test {
	static int VexNums=0;
    static int edgeNums=0;
    static int[] VexArr=null;
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入顶点数和边数");
		VexNums=scanner.nextInt();
		edgeNums=scanner.nextInt();
		VexArr=new int[VexNums];
		System.out.println("请输入顶点信息");
		for(int i=0;i<VexNums;i++) {
			VexArr[i]=scanner.nextInt();
		}
		int[][] graph=new int[VexNums][VexNums];
		createGraph(graph);//创建图
		int[] dis=new int[VexNums];
		dijkstra(graph, dis);
		int sum=0;
		for(int i=0;i<VexNums;i++) {
			System.out.print(dis[i]+" ");
			sum+=dis[i];
		}
		System.out.println("");
		System.out.println(sum);
	}
	
	public static void createGraph(int[][] graph) {
		Scanner scanner=new Scanner(System.in);
		int inf=Integer.MAX_VALUE-1234356;
		//初始化邻接矩阵
		for(int i=0;i<VexNums;i++) {
			for(int j=0;j<VexNums;j++) {
				if(i==j) {
					graph[i][j]=0;
				}
				else graph[i][j]=inf;
			}
		}
		//输入边的信息
		for(int i=0;i<edgeNums;i++) {
			System.out.println("请输入相邻的边及权值");
			int begin=scanner.nextInt();
			int over=scanner.nextInt();
			int indexBegin=getIndex(begin);
			int indexOver=getIndex(over);
			int weight=scanner.nextInt();
			//有向图
			graph[indexBegin][indexOver]=weight;
		}
	}
	
	//根据值找下标
	public static int getIndex(int x) {
		//遍历顶点数组,找到数组下标
		for(int i=0;i<VexNums;i++) {
			if(VexArr[i]==x) {
				return i;
			}
		}
		return -1;
	}
	
	//就第一个顶点到其预定点的最短路径
	public static void dijkstra(int[][] group,int[] dis) {
		for(int i=0;i<VexNums;i++) {//dis[i]表示第一个顶点到i的距离
			dis[i]=group[0][i];
		}
		Boolean[] book=new Boolean[VexNums];
		Arrays.fill(book, false);
		book[0]=true;//标记一下
		//主循环,每次求得第一个顶点到后面的顶点的最短距离
		for(int i=1;i<VexNums;i++) {
			int k=-1;
			int min=Integer.MAX_VALUE-13454432;
			
			//找到离第一个顶点最近的点
			for(int j=0;j<VexNums;j++){
				if(!book[j]&&dis[j]<min) {
					min=dis[j];
					k=j;//记录下表
				}
			}
			
			book[k]=true;//标记这个点,并且以这个点为中间点,看能不能更新其他顶点到第一个顶点的距离
			
			//现在就遍历k,看k相连的
			for(int w=0;w<VexNums;w++) {
				//如果w没有被遍历过并且第一个顶点到k的距离加上k到w的距离小于原来的第一个顶点到w的距离,则更新
				if(!book[w]&&(min+group[k][w])<dis[w]) {
					dis[w]=min+group[k][w];
				}
			}	
		}
		
		
	}
}

   接下来详细说下迪杰斯特拉的实现过程,先找到离这个源头最近的顶点k,将其标记,并且以这个点为中间点,看有没有别的顶点通过这个顶点k到源点的距离比dis记录的要小,如果有就更新。

//就第一个顶点到其预定点的最短路径
	public static void dijkstra(int[][] group,int[] dis) {
		for(int i=0;i<VexNums;i++) {//dis[i]表示第一个顶点到i的距离
			dis[i]=group[0][i];
		}
		Boolean[] book=new Boolean[VexNums];
		Arrays.fill(book, false);
		book[0]=true;//标记一下
		//主循环,每次求得第一个顶点到后面的顶点的最短距离
		for(int i=1;i<VexNums;i++) {
			int k=-1;
			int min=Integer.MAX_VALUE-13454432;
			
			//找到离第一个顶点最近的点
			for(int j=0;j<VexNums;j++){
				if(!book[j]&&dis[j]<min) {
					min=dis[j];
					k=j;//记录下表
				}
			}
			
	//标记这个点,并且以这个点为中间点,看能不能更新其他顶点到第一个顶点的距离
			book[k]=true;
			//现在就遍历k,看k相连的
			for(int w=0;w<VexNums;w++) {
		//如果w没有被遍历过
		//并且第一个顶点到k的距离加上k到w的距离小于原来的第一个顶点到w的距离
		//则更新
				if(!book[w]&&(min+group[k][w])<dis[w]) {
					dis[w]=min+group[k][w];
				}
			}	
		}

在这里插入图片描述
在这里插入图片描述

我们可以分析出来1-1是0,1-2是1,1-3是3 ,1-4是4,1-5是3,总和就是最后dis数组的和就是11

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值