您的位置:首页 > 编程语言 > Java开发

Kruskal最小生成树算法详解,以及java源代码

2016-01-07 09:55 393 查看

1.算法详解

Kruskal算法类似于Prim算法,不过Prim算法以点为单位,Kruskal主要考虑边,Kruskal算法的思想是将边排序,之后根据依次出列,如果边上的两点不在一棵树上,我们就可以将这两棵树合并成一棵树,算法思路比Prim算法更加清晰。

2. java源代码

import java.util.Arrays;
import java.util.*;
public class KruskalMy {
	static class Edge implements Comparable<Edge>
	{
        private int i,j,w;
        Edge(int i,int j,int w)
        {
        	this.i=i;
        	this.j=j;
        	this.w=w;
        }
		@Override
		public int compareTo(Edge edge) {
			if(this.w==edge.w) return 0;
			else if(this.w<edge.w) return -1;
			else return 1;
		}
		
	}
	  public static void main(String [] args){ 
	        int [] V={1,2,3,4,5,6};  
	        Edge [] E=new Edge[10];  
	        E[0]=new Edge(1,2,6);  
	        E[1]=new Edge(1,3,1);  
	        E[2]=new Edge(1,4,5);  
	        E[3]=new Edge(2,3,5);  
	        E[4]=new Edge(2,5,3);  
	        E[5]=new Edge(3,4,5);  
	        E[6]=new Edge(3,5,6);  
	        E[7]=new Edge(3,6,4);  
	        E[8]=new Edge(4,6,2);  
	        E[9]=new Edge(5,6,6);  
	        kruskal(V, E);  
	    }  
	  
	  public static void kruskal(int [] V,Edge [] E)
	  {
		  Arrays.sort(E);
		  int m=V.length;
		  int n=E.length;
		  //每个set表示一棵树,list表示森林
		  ArrayList<HashSet<Integer>> list=new ArrayList<HashSet<Integer>>();
		  ArrayList<Edge> edges=new ArrayList<Edge>();
		  //初始化每个点构成一棵树
		  for(int i=0;i<m;i++)
		  {
			  HashSet<Integer> set= new HashSet<Integer>();
			  set.add(V[i]);
			  list.add(set);
		  }
		  //每个边依次出列
		  for(int i=0;i<n;i++)
		  {
			  Edge edge=E[i];
			  int a=edge.i;
			  int b=edge.j;
			  int counta=-1;
			  int countb=-1;
			  //首先要找到边上两点所在的树
			  for(int j=0;j<list.size();j++){
				  HashSet<Integer> set=list.get(j);
				  if(set.contains(a))
				  {
					  counta=j;
				  }
				  if(set.contains(b))
				  {
					  countb=j;
				  }
			  }
			  //没找到点
			  if(counta==-1||countb==-1)
			  {
				  return;
			  }
			  else
			  {
				  //两点在不同的树
				  if(counta!=countb)
				  {
					  HashSet<Integer> set1=list.get(counta);
					  HashSet<Integer> set2=list.get(countb);
					  set1.addAll(set2);
					  //删除集合的时候要注意。连续删除两个集合
					  if(counta<countb){
					    list.remove(counta);
					    list.remove(countb-1);
					  }
					  else
					  {
						  list.remove(countb);
						  list.remove(counta-1);
					  }
					  list.add(set1);
					  edges.add(edge);
					  System.out.println("将边"+edge.i+"--->"+edge.j+"加入,其权值为"+edge.w);
				  }
				  else
				  {
					  System.out.println("不能加入"+edge.i+"--->"+edge.j+"两点在同一个树中");
				  }
			  }
		  }
	  }
}

3.运行结果

将边1--->3加入,其权值为1

将边4--->6加入,其权值为2

将边2--->5加入,其权值为3

将边3--->6加入,其权值为4

不能加入1--->4两点在同一个树中

将边2--->3加入,其权值为5

不能加入3--->4两点在同一个树中

不能加入1--->2两点在同一个树中

不能加入3--->5两点在同一个树中

不能加入5--->6两点在同一个树中



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: