prim算法:
先从图中随机选取一个点,从它的边中选择一个最小的进行扩展。
扩展完之后这两个点变成一个集合,他们的边集也会进行相应的扩展,再从扩展的边集中找一个最小的边进行扩展。
扩展的时候要注意,扩展的边一定不能是集合内部的,就不能是边的to节点是集合内部的。
一直循环,直到所有的点都扩展完了就行了。
public static Set<Edge> primMST(Graph graph){
PriorityQueue<Edge> priority = new PriorityQueue<Edge>(new EdgeCompa());
Set<Edge> result = new HashSet<Edge>();
Set<Node> nodeSet = new HashSet<Node>();
for(Node node:graph.nodes.values()) {//随便挑选一个点
if(!nodeSet.contains(node)) {//如果点集合中不包含这个点
nodeSet.add(node);//加入点集
for(Edge edge:node.edges) {
priority.add(edge);//把这个点的边集加入优先级队列中
}
while(!priority.isEmpty()) {
Edge edge = priority.poll();//从优先级队列中弹出一个最小边
if(!nodeSet.contains(edge.to)) {//看这条边是在点集内部还是外部
result.add(edge);
nodeSet.add(edge.to);//在外部就加入到点集内
for(Edge e:edge.to.edges) {
priority.add(e);//边集也要扩展。
}
}
}
}
}
return result;
}
代码中这个最大的for循环,如果是联通图的话其实是没有用的,如果是森林的话,图是分成几块的,那么这个for循环就可以在每一块中生成一个最小生成树。