一、Kruskal
1.算法思想:每次挑最小的边生成子树,不断合并子树生成最小子树
2.算法步骤
(1)构造一个边类,放两个顶点和边长,还有一个isvisit用来知道该边是否被访问过
class Edge // 边
{
String A;
String B;
int length;
boolean isvisit= false ;
// getter setter
}
(2)初始化数据
HashMap<String,String> Points= new HashMap<> ();//放顶点,和顶点所属的子树群
ArrayList <Edge> Edges= new ArrayList<> ();//放边的信息
Edges.add( new Edge("A","B",2 ));
Edges.add( new Edge("A","D",4 ));
Edges.add( new Edge("A","C",5 ));
Edges.add( new Edge("B","C",4 ));
Edges.add( new Edge("C","D",6 ));
Edges.add( new Edge("B","E",5 ));
Edges.add( new Edge("D","F",7 ));
Edges.add( new Edge("C","E",3 ));
Edges.add( new Edge("C","F",4 ));
Edges.add( new Edge("E","F",1 ));
printKruskal(Points,Edges);//调用函数
(3)写工具函数
selectMin()挑选最小边
getGroup() 获得子树群信息,用来合并子树
private static Edge selectMin(ArrayList<Edge> edges) {
int min=999 ;
int index=-1 ;
for ( int i=0;i<edges.size();i++ )
{
if (edges.get(i).isvisit== false &&edges.get(i).getLength()< min)
{
index = i;
min = edges.get(i).getLength();
}
}
edges.get(index).setIsvisit( true );
// System.out.println("!"+edges.get(index).getA()+"<=>"+edges.get(index).getB()+" length="+edges.get(index).getLength());
return edges.get(index);
}
private static ArrayList<String> getGroup(String str,HashMap<String, String> points)
{
ArrayList <String> result= new ArrayList<> ();
for (Entry<String,String> entry:points.entrySet())
{
if (entry.getValue().equals(str))
{
result.add(entry.getKey());
}
}
return result;
}
(4)逻辑处理和输出结果
private static void printKruskal(HashMap<String, String> points,ArrayList<Edge> edges)
{
ArrayList <Edge> result= new ArrayList<> ();
while (result.size()<5 )
{
Edge e = selectMin(edges);
while (points.get(e.getA())!= null && points.get(e.getA()).equals(points.get(e.getB())))
{
e = selectMin(edges);
}
if (points.get(e.getA())== null &&points.get(e.getA())== null )
{
points.put(e.getA(), e.getA());
points.put(e.getB(), e.getA());
}
else if (points.get(e.getA())== null )
{
points.put(e.getA(), e.getB());
}
else if (points.get(e.getB())== null )
{
points.put(e.getB(), e.getA());
}
else
{
ArrayList <String> groupB= getGroup(points.get(e.getB()),points);
for (String str:groupB)
{
points.put(str, e.getA());
}
}
result.add(e);
System.out.println(e.getA() +"<=>"+e.getB()+" length="+ e.getLength());
}
}
3.结果截图
二、Prim
1.算法思想:从一个顶点出发,不断挑选已有数可到达的最小边,直到生成最小生成树
2.算法步骤:
(1)构造边类:同上
(2)数据初始化:同上
(3)逻辑处理:
ArrayList<Edge> result= new ArrayList<> ();
ArrayList <String> now= new ArrayList<> ();//已有顶点
now.add( "A"); // 从A出发
while (now.size()<6 )
{
int min=999 ;
Edge minEdge = null ;
for (Edge e:edges)
{
for ( int i=0;i<now.size();i++ )
{
if (now.get(i).equals(e.getA())|| now.get(i).equals(e.getB()))
{
if (!e.isIsvisit()&&e.getLength()< min)
{
min = e.getLength();
minEdge = e;
}
}
}
}
minEdge.setIsvisit( true );
if (now.contains(minEdge.getA()))
{
now.add(minEdge.getB());
}
else
{
now.add(minEdge.getA());
}
System.out.println(minEdge.getA() +"<=>"+minEdge.getB()+" length="+ minEdge.getLength());
result.add(minEdge);
}
3.结果截图
查看更多关于图的最小子树算法--Kruskal和Prim的详细内容...
声明:本文来自网络,不代表【好得很程序员自学网】立场,转载请注明出处:http://haodehen.cn/did238265