Kruskal算法求图的最小生成树:
Kruskal算法本质上上是贪心算法,即每次从图中选取权重最小的安全边(安全边就是加入最小生成树中不会形成回路的边)加入最小生成树(刚开始为空集)中,然后把改边从原图中剔除,继续重复前面的步骤,直到从原图中剔除所有的边或者原图中所有顶点均加入到生成树中。
下面就是由一个图的邻接矩阵求其最小生成树的代码:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package kruskal;
import java.util.*;
/**
*
* @author liuzhenzhao
*/
public class Kruskal {
/**
* @param args the command line arguments
*/
class Edge implements Comparable<Edge>
{
int start;
int end;
int weight;
public Edge(int start,int end,int weight)
{
this.start=start;
this.end=end;
this.weight=weight;
}
public Edge(Edge o)
{
this.start=o.start;
this.end=o.end;
this.weight=o.weight;
}
@Override
public int compareTo(Edge o)
{
return this.weight-o.weight;
}
}
ArrayList<Edge>MST_Kruskal(int [][]G)
{
ArrayList <Edge>list=new ArrayList<Edge>();
ArrayList <Edge>temp=new ArrayList<Edge>();
Set<Integer> set=new TreeSet<Integer>();
if(G.length==0)
{
return list;
}
else
{
for(int i=0;i<G.length;i++)
{
for(int j=i+1;j<G[i].length;j++)
{
if(G[i][j]>0)
{
temp.add(new Edge(i,j,G[i][j]));
}
}
}
Collections.sort(temp);//对所有的边进行排序
//下面依次访问权重最小的边
for(int i=0;i<temp.size();i++)
{
Edge q=temp.get(i);
if(set.contains(q.start)&&set.contains(q.end))//不添加重复的边
continue;
//下面两个判断保证不会形成回路
if(!set.contains(q.start))
set.add(q.start);
if(!set.contains(q.end))
set.add(q.end);
list.add(new Edge(q));//将安全的边加入list
; }
return list;
}
}
public static void main(String[] args)
{
Scanner in=new Scanner(System.in);
int m=0,n=0;
if(in.hasNextInt())
m=in.nextInt();
int [][]G=new int[m][m];
for(int i=0;i<m;i++)
{
for(int j=i+1;j<m;j++)
{
if(in.hasNextInt())
G[i][j]=in.nextInt();
}
}
Kruskal obj=new Kruskal();
ArrayList<Edge> list=obj.MST_Kruskal(G);
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i).start+"--"+list.get(i).end+"("+list.get(i).weight+")");
}
}
}