图的最小生成树kruskal算法总结


kruskal算法的思想

假如N={V,{E}}是连通网,那么最小生成树的初始状态是由V个顶点自成连通分量构成的一片森林。在E中选择权值最小的边,当该边对应的两个顶点在不同分量时,则将该边加入到最小生成树中,否则的舍去,再选择下一条代价最小的边,如此循环,直到所有的连通分量连接变成一个连通分量为止。


看看具体代码

public void minSpanTree_kurskal(Edges[] edges){  //edges已按照权值大小进行了非递减排序
		
		Integer parent[] = new Integer[edges.length];
		int n,m;
		for(int i=0;i<edges.length;i++){   //初始化parent[]全部元素为0;
			parent[i] = 0;
		}
		
		for(int i=0;i<edges.length;i++){
			n = find(parent,edges[i].begin);  //寻找edges[i].begin所在连通分量的根顶点
			m = find(parent,edges[i].end);  //寻找edges[i].end所在连通分量的根顶点
			
			if(n!=m){      // 如果根结点不同说明dges[i].begin和dges[i].end在不同分量上
				parent[n] = m;
				System.out.println("begin="+edges[i].begin+","+"end="+edges[i].end+","+"weight="+edges[i].weight);
			}
		}
			
	}
private int find(Integer[] parent, int f) {
		
		while(parent[f]>0)
			f = parent[f];
		return f;
		
	}



这里存在一个问题:如何判断2个顶点在同一个连通分量?

每个连通分量上都有一个顶点代表整个连通分量,我们把它叫做根顶点,也就是通过find()方法我们可以找到该顶点所在连通分量的根顶点,如果两个顶点的根顶点相同,则代表这两个顶点在同一个连通分量上,反之则不是。

算法运行详解

1.用边集数组存储图,然后再按照权值大小进行非递减排好序,结果如下图所示




2.初始化parent[],结果如下图

值全部为0也就代表每一个顶点自称一个连通分量


3.取权值最小的边


4.调用find方法得到顶点所在连通分量的根顶点

注:其实每个连通分量的全部顶点可以看成类似树,但此树的边总是从子结点指向父节点,最后树的根即为根顶点,

如当循环到edges[6]时,有如下图所示结果


如上图所示,通过parent[]数组可以画出两个类似树的连通分量,其中7和6分别为森林中两个不同的连通分量的根顶点。如要判断顶点5所在连通分量的根顶点是什么,图中可看到5的父结点为8,8的父节点为6,6的父结点为空,说明6即为连通分量的根节点。


5.如果两个顶点的根顶点不同,说明两个顶点在不同的连通分量上,将该边加入最小生成树中,否则舍弃。


6.取最小权值的边不断循环......







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值