1.算法思想:
Prime算法:最小生成树算法之一(从点考虑),要求图为无向图,假设图为:
A
6 / 1| \5
/ | \
B -- C -- D
\ 5 / \ 5 /
3 \ /6 4\ /2
E --- F
6
算法思想:
1. 随机选一个点(以A为起始点)
2. 将和A点相连的边加入到被解锁的边后{AB,AC,AD},被解锁的点{A}
3. 从被解锁的边中选中一个值最小的边AC,C未被解锁,所以可以将其从被解锁的边中删除,此时被解锁的边{AB,AD},被解锁的点{A,C}
4. 将和C相连的边加入到被解锁的边后{AB,AD,CA,CB,CD,CE,CF}
5. 从被解锁的边中选中一个值最小的边CA,A被解锁,继续选次小的边直到to节点未被解锁,符合条件的边为CF,所以可以将其从被解锁的边中删除,此时被解锁的边{AB,AD,CA,CB,CD,CE},被解锁的点{A,C,F}
6. 将和F相连的边加入到被解锁的边后{AB,AD,CA,CB,CD,CE,FE,FC,FD}
7. 从被解锁的边中选中一个值最小的边FD(不再赘述找CA),D未被解锁,所以可以将其从被解锁的边中删除,此时被解锁的边{AB,AD,CA,CB,CD,CE,FE,FC},被解锁的点{A,C,F,D}
8. 将和D相连的边加入到被解锁的边后{AB,AD,CA,CB,CD,CE,FE,FC,DF,DC,DA}
9. 从被解锁的边中选中一个值最小的边DF(不再赘述找CA),F被解锁,继续选次小的边直到to节点未被解锁,符合条件的边为CB,所以可以将其从被解锁的边中删除,此时被解锁的边{AB,AD,CA,CD,CE,FE,FC,DF,DC,DA},被解锁的点{A,C,F,D,B}
10.将和B相连的边加入到被解锁的边后{AB,AD,CA,CD,CE,FE,FC,DF,DC,DA,BE,BC,BA}
11.依次类推找到BE,解锁E点,所有点都被解锁
2.代码实现:
public class Prime {
public static class EdgeComparator implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
}
public static Set<Edge> primMST(Graph graph){
PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
HashSet<Node> set = new HashSet<>();
Set<Edge> result = new HashSet<>();
for (Node node : graph.nodes.values()){
if (!set.contains(node)){
set.add(node);
for (Edge edge : node.edges){
priorityQueue.add(edge);
}
while (!priorityQueue.isEmpty()){
Edge edge = priorityQueue.poll();
Node toNode = edge.to;
if (!set.contains(toNode)){
result.add(edge);
set.add(toNode);
for (Edge nextEdge : toNode.edges){
priorityQueue.add(nextEdge);
}
}
}
}
}
return result;
}
}