最小生成树(Prim和Kruscal)

因为不是经常用到这些算法,这里写一下自己的理解。待日后用到的时候可以重新看一下。


Prim算法,主要是将各个点分到S集合,U集合。S集合是已经都确定最短路径的,U集合是未确定的。(这里通过将)


首先将与起始点相连的各个点装到lowcost里面,并将起始点到达该点的前一个点装入closest里(供查找路径使用)。


然后循环剩下的n-1个点,找出与起始点最近的一个点k。


然后更新lowcost与closest(将k点到达的i点的距离与起始点直接到达i点的距离比较,是否经过k点距离更近?如果是,closest[i] = k ,起始点到达i点前一个点是点k)


public class Prim {

	private MGraph g;
	
	private final int INF = 32767;
	
	private final int MAX = 100;
	
	public Prim(MGraph g){
		
		this.g = g;
		
	}
	
	private class MGraph{
		
		private int[][] edges;//点到点的距离
		
		private int n;//总共多少个点
		
	}
	
	void Make_MSP(int v){
		
		int lowcost[] = new int[MAX];//保存 与已经描绘出的路径中各个点最近的    距离
		int closest[] = new int[MAX];//保存 最近的距离是由已经描绘出的路径中的哪个顶点最为媒介搭桥的
		
		int min,k = 0;
		
		for(int i = 0 ; i < g.n ; i ++){//初始化lowcost、closest
			
			lowcost[i] = g.edges[v][i];
			closest[i] = v;
			
		}
		
		for(int i = 1 ; i < g.n ; i ++){
			
			min = INF;
			
			for(int j = 0 ; j < g.n ; j++){//得出v点到其他点中最短路径的点
				
				if(lowcost[j] != 0 && lowcost[j] < min){
					
					min = lowcost[j];
					
					k = j;
					
				}
				
			}
			
			lowcost[k] = 0;//标记K已经加入U。
			
			for(int j = 0 ; j < g.n ; j ++){
				
				if(g.edges[k][j] != 0 && g.edges[k][j] < lowcost[j]){
					
					closest[j] = k;
					
					lowcost[j] = g.edges[k][j];
					
				}
				
			}
			
		}
		
	}
	
}


Kruscal:


克鲁斯科尔算法用于 边少,点多的时候。


主要的思想:将点与点之间距离短的从小到大连接起来,前提他们不会构成一个回路(这里是通过判断该点是否在同一个集合里来判断的是否构成回路,用了vset数组),就ok了


public class Kruskal {
	
	private final int INF = 32767;
	private final int MAX = 100;
	
	
	private class MGraph{
		
		private int n;
		private int[][] edges;
		
	}
	
	void Make_MSP(MGraph g){
		
		Edge[] E = new Edge[MAX];
		
		int k = 0,u1,v1,sn1,sn2;
		int vset[] = new int[MAX];//辅助数组
		
		for(int i = 0 ; i < g.n ; i ++){
			
			for(int j = 0 ; j < g.n ; j ++){
				
				if (g.edges[i][j] != 0 && g.edges[i][j] != INF) {
					
					E[k] = new Edge();
					E[k].u = i;
					E[k].v = j;
					E[k].w = g.edges[i][j];
					k++;
					
				}
				
			}
			
		}
		
		InsertSort ise = new InsertSort();
		
		ise.Sort(E);//插入排序,将点与点的距离按从小到大排序
		
		for(int i = 0 ; i < g.n ; i ++){
			
			vset[i] = i;
			
		}
		
		k = 1;
		int j = 0;
		while(k < g.n){
			
			u1 = E[j].u;
			v1 = E[j].v;
			
			sn1 = vset[u1];
			sn2 = vset[v1];
			
			if (sn1 != sn2) {
				
				k++;
				
				for(int i = 0 ; i < g.n ; i ++){
					
					if (vset[i] == sn2) {
						
						vset[i] = sn1;
						
					}
				}
				
			}
			
			j++;
			
		}
		
	}
	
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值