算法:最短路径和最小生成树

1.最短路径

有Dijkstra算法和Floyd算法

算法
无权图BFS
有权图 单原Dijkstra 或者Floyd
有权图 多原Floyd 或者多次Dijkstra

复杂度:

  • Dijkstra:n^2, 查找min distance的时候开业改用堆排序或者PriorityQueue,复杂度降为nlogn
  • Floyd:n^3,空间复杂度 N的平方,dist[][] 可以一次性求出所有点之间的最短路径,适合多原最短路径问题
import java.util.Arrays;
import java.util.HashMap;

public class TestMinDistance {
	static int MAX = 1000;
	//Floyd算法
	public int Floyd(int[][] map ,int start,int end) {
		int len = map.length;
		int[][] dist = new int[len][len];
		//init
		for(int i =0;i<len;i++) {
			for(int j =0;j<len;j++) {
				dist[i][j]=map[i][j];
			}
		}
		
		//duyu K node
		for(int k =0;k<len;k++) { //用每个节点,去更新
			for(int i=0;i<len;i++) {
				for(int j =0;j<len;j++) {
					dist[i][j] = Math.min(dist[i][j], dist[i][k]+dist[k][j]);
				}
			}
		}
		return dist[start][end];
	}
	//Dijkstra算法
	public int Dijkstra(int[][] map,int start,int end) {
		int len = map.length;
		int[] distance = new int[len];
		Arrays.fill(distance,MAX);
		boolean[]  isVisited = new boolean[len];
		
		//先通过起点设置distance
		isVisited[start] =true;
		for(int i = 0;i<len;i++) {
			distance[i] = map[start][i];
			
		}
		
		//主循环,每次选择distance中未标记的最小点,用这个点去更新 distance
		for(int i =1;i<len;i++) {
			
			//find min
			//这里可以用堆排序,或者PriorityQueue,这样复杂度为nlogn
			int min = MAX;
			int index = -1;
			for(int j =0;j<len;j++) {
				if(isVisited[j])continue;
				//System.out.println(1);
				if(min > distance[j]) {
					min = distance[j];
					index =j;
					
				}
			}
			
			isVisited[index] = true;
			for(int j =0;j<len;j++) {
				int dis = distance[index] +map[index][j];
				if(distance[j] > dis ) {
					distance[j] = dis;
					
				}
				System.out.print(distance[j]+" ");
			}
			
			System.out.println();
		}
		return distance[end];
		
	}
	
	public static void main(String[] args) {
		int MAX = TestDijkstra.MAX;
		int[][] map = { //基于邻接矩阵的
				{0,1,5,10,MAX},
				{1,0,2,MAX,8},
				{5,2,0,2,3},
				{10,MAX,2,0,1},
				{MAX,8,3,1,0}
		};
		TestMinDistancetd = new TestMinDistance();
		
		System.out.println(td.Dijkstra(map, 3, 4));
		System.out.println(td.Floyd(map, 0, 3));
	}

}

2.最小生成树算法

在这里插入图片描述

prim算法和Dijkstra算法很像,只是求distance时候有点差别

在这里插入图片描述
这里实现了prim算法

import java.util.Arrays;

public class TestMinProduceTree {
	static int MAX = 1000;
	//最小生成树算法  prim  
	//和dijkstra算法的区别就是,每次更新distance的时候,只需要更新这个点到当前集合的值,而不是到原点的值
	//distance 不需要加上 前面节点到原点的值
	public int Prim(int[][] map, int start) {
		int len = map.length;
		int[] distance = new int[len]; //更新当前集合到剩下节点的距离
		Arrays.fill(distance, MAX);
		
		boolean[] isVisited = new boolean[len];
		int[] node = new int[len];//保存节点加入生成树的顺序
		int sum =0;//最小生成树的代价
		
		//首次访问的节点加入
		node[0] = start;
		isVisited[start] = true;
		for(int i =0;i<len;i++) {
			distance[i] = map[start][i];
		}
		
		for(int i =1;i<len;i++) {
			//find min
			int min = MAX;
			int index = -1;
			for(int j=0;j<len;j++) {
				if(isVisited[j])continue;
				if(min > distance[j]) {
					min = distance[j];
					index = j;
				}
			}
			
			//mark index node
			isVisited[index] = true;
			sum += min;
			System.out.print(min+" ");
			node[i] = index;
			
			//new node update distance
			for(int j=0;j<len;j++) {
				if(isVisited[j])continue;
				if(distance[j] > map[index][j]) { //最小生成树 这里跟新distance 和dijkstra不一样,更简单,其他都一样
					distance[j] = map[index][j];
				}
				
			}
		}
		for(int i:node) {
			System.out.print(i+" ");
		}
		return sum;
		
	}
	public static void main(String[] args) {
		int MAX = TestMinProduceTree.MAX;
		int[][] map = {
				{0,5,1,5,MAX,MAX},
				{5,0,5,MAX,3,MAX},
				{1,5,0,5,6,4},
				{5,MAX,5,0,MAX,2},
				{0,3,6,MAX,0,6},
				{MAX,MAX,4,2,6,0}
		};
		TestMinProduceTree tt = new TestMinProduceTree();
		System.out.println(tt.Prim(map, 2));
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值