普利姆算法(Prim)

9 篇文章 0 订阅
6 篇文章 0 订阅
普利姆算法和克鲁斯卡尔算法都是求连接图中所有结点的最短路径,也就是最小生成树。普利姆算法其实就是不断获取已经访问结点和未访问结点之间的最短边来获取所有结点间的最短路径,也可以认为是广度+贪婪。
接下来看算法的实现,这里只给出关键代码,基本的图数据结构可以自己实现。
//结点数量
private int[] vertexs;
//矩阵实现图
private int[][] edges;
//n:为指定开始的结点
public void prim(Graph graph , int n) {
	//这里我们需要一个辅助数组来标识结点是否已经访问
	boolean[] rank = new boolean[];
	//第一次我们需要把结点设置为已经访问
	rank[n] = true;
	//用来标记最短边的两个结点
	int a = -1;
	int b = -1;
	//获取已经访问结点,和未访问结点之间最小一条边的权值,这里需要设置大点,防止最短的没有获取到
	int min = 10000;
	//第一层表示每次获取一条两个集合之间最短的一条边,n个结点有n-1条边
	for(int i = 0; i < vertexs.length; i++) {
		//广度遍历结点,获取最小的边
		for(int j = 0; i < vertexs.length; j++) {
			for(int k = 0; k < vertexs.length; k++) {
				//最关键的在这个判断,我们需要寻找两个集合之间最短的一条边,那么我们再广度遍历时候,
				//只要一个点访问过,一个没访问,这里不需要判断是否成环,因为成环是需要两个都访问过才能成
				if(rank[j] && !rank[k] && edges[j][k] < min) {
					min = edges[j][k];
					a = j;
					b = k;
				}
			}
		}
	//最小边已经找到了,我们可以把这个结点设置成已经访问了
	rank[b] = true;
	//需要更新min的值,防止错过最小值
	min = 10000;
	}
}

到此普利姆算法就算结束了,可能光看文字和代码还是很难理解,其实就是一个点,已经找到的点和未找到的点之间获取一条相通的最小边,大家可以去B站看看普利姆算法的视频动画,这样理解起来还是很直观的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值