图论最短路径算法 Java实现

Dijkstra算法

  • 问题描述:
    单源最短路径问题
public class Dijkstra {
	public static int inf=65535;
	public static void dijkstra(int map[][],int n,int v0) {
		int path[]=new int[n];//path[v]表示v到v0的最短路径的前驱顶点
		int minValue[]=new int[n];//minValue[v]存储v0到v的最短路径值
		int visit[]=new int[n];//visit[v]表示v是否已经求得最短路径
		int v,w,k,min;
		//初始化数据
		for(v=0;v<n;v++)
		{
			visit[v]=0;
			minValue[v]=map[v0][v];
			path[v]=v0;
		}
		minValue[v0]=0;
		visit[v0]=1;
		k=0;
		//开始主循环,每一求得v0到某点v的最短路径
		for(v=1;v<n;v++)
		{
			min=inf;
			for(w=0;w<n;w++)
			{
				if(visit[w]==0&&minValue[w]<min)
				{
					k=w;
					min=minValue[w];
				}
			}
			visit[k]=1;
			//修正当前最短路径和距离
			for(w=0;w<n;w++)
			{
				if(visit[w]==0&&(min+map[k][w])<minValue[w])
				{
					minValue[w]=min+map[k][w];
					path[w]=k;
				}
			}
		}
		show(path,minValue,n);
	}
	public static void show(int path[],int minValue[],int n) {
		for(int v=0;v<n;v++)
		{
			System.out.print(path[v]+" ");
		}
		System.out.println("");
		for(int v=0;v<n;v++)
		{
			System.out.print(minValue[v]+" ");
		}
	}
	public static void main(String[] args) {
		int map[][]= {  {0,1,5,inf,inf,inf,inf,inf,inf},
					    {1,0,3,7,5,inf,inf,inf,inf},
						{5,3,0,inf,1,7,inf,inf,inf},
						{inf,7,inf,0,2,inf,3,inf,inf},
						{inf,5,1,2,0,3,6,9,inf},
						{inf,inf,7,inf,3,0,inf,5,inf},
						{inf,inf,inf,3,6,inf,0,2,7},
						{inf,inf,inf,inf,9,5,2,0,4},
						{inf,inf,inf,inf,inf,inf,7,4,0},
					};
		dijkstra(map,map.length,0);
	}
}
  • 时间复杂度: O ( n 2 ) O(n^2) O(n2)

Dijkstra算法改进 优先队列实现

//优先队列实现
public static void dijkstra_priorityQueue(int map[][],int n,int v0) {
	class Node implements Comparable<Node> {
		public int index;
		public int weight;
		public Node(int index,int weight){
			this.index=index;
			this.weight=weight;
		}
		@Override
		public int compareTo(Node o) {
			return this.weight-o.weight;
		}
	}
	int path[]=new int[n]; 
	int visit[]=new int[n]; 
	int minValue[]=new int[n];
	int k,w;
	PriorityQueue<Node>qu=new PriorityQueue<>();
	visit[v0]=1;
	minValue[v0]=0;
	for(int v=0;v<n;v++)
	{
		visit[v]=0;
		minValue[v]=map[v0][v];
		path[v]=v0;
		qu.offer(new Node(v,minValue[v]));
	}
	while(!qu.isEmpty()) {
		Node node=qu.poll();
		k=node.index;
		w=node.weight;
		if(visit[k]==1) {
			continue;
		}
		visit[k]=1;
		for(int i=0;i<n;i++) {
			if(visit[i]==0&&w+map[k][i]<minValue[i]) {
				
				qu.offer(new Node(i,w+map[k][i]));
				minValue[i]=w+map[k][i];
				path[i]=k;
			}
		}
	}
	show(path,minValue,n);
}

Floyd算法

public class Floyd {
	public static int inf=65535;
	public static void floyd(int map[][],int n) {
		int path[][]=new int[n][n]; 
		int minValue[][]=new int[n][n]; 
		int v,w,k;
		//初始化
		for(v=0;v<n;v++)
		{
			for(w=0;w<n;w++)
			{
				minValue[v][w]=map[v][w];
				path[v][w]=w;
			}
		}
		for(k=0;k<n;k++)
		{
			for(v=0;v<n;v++)
			{
				for(w=0;w<n;w++)
				{
					if(minValue[v][w]>(minValue[v][k]+minValue[k][w]))
					{
						minValue[v][w]=minValue[v][k]+minValue[k][w];
						path[v][w]=path[v][k];
					}
				}
			}
		}
		show(path,minValue,n);
	}
	public static void show(int path[][],int minValue[][],int n) {
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				System.out.print(path[i][j]+" ");
			}
			System.out.println("");
		}
		System.out.println("");
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				System.out.print(minValue[i][j]+" ");
			}
			System.out.println("");
		}
	}
	public static void main(String[] args) {
		int map[][]= {  {0,1,5,inf,inf,inf,inf,inf,inf},
					    {1,0,3,7,5,inf,inf,inf,inf},
						{5,3,0,inf,1,7,inf,inf,inf},
						{inf,7,inf,0,2,inf,3,inf,inf},
						{inf,5,1,2,0,3,6,9,inf},
						{inf,inf,7,inf,3,0,inf,5,inf},
						{inf,inf,inf,3,6,inf,0,2,7},
						{inf,inf,inf,inf,9,5,2,0,4},
						{inf,inf,inf,inf,inf,inf,7,4,0},
					};
		floyd(map,map.length);
	}
}
  • 时间复杂度: O ( n 3 ) O(n^3) O(n3)

参考书籍:《大话数据结构》

  • 0
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:1024 设计师:我叫白小胖 返回首页
评论

打赏作者

lzrrick

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值