连通图里的所有顶点,且其所有边的权值之和亦为最小。
选择一个点作为开始节点,遍历节点所有的边入优先级队列,选择权重最小的边,判断边的to节点是否已经加入过,如果已经加入过,则继续循环取出优先级队列中的节点,没有加入过,就将节点加入进来,再继续遍历to节点的所有边进入优先级队列,循环这些操作,直到优先级队列全部为空
优先级队列,实际就是小根堆,每次取出的都是最小的元素
public class Prim {
public static class EdgeComparator implements Comparator<Edge> {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight - o2.weight;
}
}
private static Set<Edge> primMST(Graph graph){
PriorityQueue<Edge> queue = new PriorityQueue<>(new EdgeComparator());
//控制节点重复添加
HashSet<Node> set = new HashSet<>();
//返回数据
Set<Edge> res = new HashSet<>();
for (Node node : graph.nodes.values()) {
//判断节点是否已经加入过
if (!set.contains(node)){
//加入节点
set.add(node);
//遍历节点所有的边,加入进优先级队列
for (Edge edge : node.edges) {
queue.add(edge);
}
//取出优先级队列中的边
while (!queue.isEmpty()){
Edge edge = queue.poll();
Node to = edge.to;
//边的to节点没有加入过,加入
if (!set.contains(to)){
set.add(to);
res.add(edge);
//将to节点的所有边入队列
for (Edge next : to.edges) {
queue.add(next);
}
}
}
}
}
return res;
}
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
Node node6 = new Node(6);
Edge edge1 = new Edge(6, node1, node2);
Edge edge11 = new Edge(6, node2, node1);
Edge edge2 = new Edge(1, node1, node3);
Edge edge21 = new Edge(1, node3, node1);
Edge edge3 = new Edge(5, node1, node4);
Edge edge31 = new Edge(5, node4, node1);
Edge edge4 = new Edge(5, node2, node3);
Edge edge41 = new Edge(5, node3, node2);
Edge edge5 = new Edge(3, node2, node5);
Edge edge51 = new Edge(3, node5, node2);
Edge edge6 = new Edge(5, node3, node4);
Edge edge61 = new Edge(5, node4, node3);
Edge edge7 = new Edge(6, node3, node5);
Edge edge71 = new Edge(6, node5, node3);
Edge edge8 = new Edge(4, node3, node6);
Edge edge81 = new Edge(4, node6, node3);
Edge edge9 = new Edge(2, node4, node6);
Edge edge91 = new Edge(2, node6, node4);
Edge edge10 = new Edge(6, node5, node6);
Edge edge101 = new Edge(6, node6, node5);
ArrayList<Edge> list1 = new ArrayList<>();
list1.add(edge1);
list1.add(edge2);
list1.add(edge3);
node1.edges = list1;
ArrayList<Edge> list2 = new ArrayList<>();
list2.add(edge11);
list2.add(edge4);
list2.add(edge5);
node2.edges = list2;
ArrayList<Edge> list3 = new ArrayList<>();
list3.add(edge21);
list3.add(edge41);
list3.add(edge6);
list3.add(edge7);
list3.add(edge8);
node3.edges = list3;
ArrayList<Edge> list4 = new ArrayList<>();
list4.add(edge31);
list4.add(edge61);
list4.add(edge9);
node4.edges = list4;
ArrayList<Edge> list5 = new ArrayList<>();
list5.add(edge51);
list5.add(edge71);
list5.add(edge10);
node5.edges = list5;
ArrayList<Edge> list6 = new ArrayList<>();
list6.add(edge91);
list6.add(edge81);
list6.add(edge101);
node6.edges = list6;
HashMap<Integer, Node> map = new HashMap<>();
map.put(1, node1);
map.put(2, node2);
map.put(3, node3);
map.put(4, node4);
map.put(5, node5);
map.put(6, node6);
HashSet<Edge> edges = new HashSet<>();
edges.add(edge1);
edges.add(edge2);
edges.add(edge3);
edges.add(edge4);
edges.add(edge5);
edges.add(edge6);
edges.add(edge7);
edges.add(edge8);
edges.add(edge9);
edges.add(edge10);
Graph graph = new Graph();
graph.edges = edges;
graph.nodes = map;
Set<Edge> set = primMST(graph);
System.out.println();
}
}