1.Kruskal
public static HashSet<Edge> KruskalSTL(Graph graph){
UnionFind unionFind = new UnionFind();
unionFind.makeSets(graph.nodes.values());
HashSet<Edge> set = new HashSet<>(); //需要返回的边集合
if(graph==null) return set;
PriorityQueue<Edge> queue = new PriorityQueue<>(new Comparator<Edge>() {
@Override
public int compare(Edge o1, Edge o2) {
return o1.weight-o2.weight;
}
});
for (Edge edge : graph.edges) { // 将所有的边放入队列
queue.add(edge);
}
while (!queue.isEmpty()){
Edge curEdge = queue.poll();
//检查当前边curEdge的from和to节点是否属于一个集合
if(!unionFind.isSameSet(curEdge.from,curEdge.to)){
//不在同一集合下
set.add(curEdge);
unionFind.union(curEdge.from,curEdge.to);
}
}
return set;
}
2.Plim
public static Set<Edge> PrimSTL(Graph graph) {
HashSet<Edge> res = new HashSet<>();
if (graph == null) return res;
//set用于记录已经连通的节点
HashSet<Node> set = new HashSet<>();
//queue用于记录当前节点的边
PriorityQueue<Edge> queue = new PriorityQueue<>();
//for循环是针对森林,如果有未连通的分量可以,通过for循环可以找到,分量内部生成最小生成树
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 curEdge = queue.poll();
Node toNode = curEdge.to;
//如果指向的节点不在集合里,将指向该节点边添加到最小生成树里,将指向的节点放入集合,并将指向节点所有边放入队列
if(!set.contains(toNode)) {
set.add(toNode);
res.add(curEdge);
for (Edge edge : toNode.edges) {
queue.add(edge);
}
}
}
}
}
return res;
}
3.Dijkstra
public static Map<Node,Integer> Dijkstra(Node node) {
HashMap<Node, Integer> distanceMap = new HashMap<>(); //map key:表示图中的一个节点
//value:表示从node到key的最短路径
if(node==null) return distanceMap;
HashSet<Node> selectedNodes = new HashSet<>(); // set用于存放已经更新完成的节点,以后不再更新
distanceMap.put(node,0); // 将源头节点放入map中
Node minNode = getMinAndUnelectedNode(distanceMap,selectedNodes); //选出未更新完成的节点中最小的一个
while (minNode!=null) {
int distance = distanceMap.get(minNode);
for (Edge edge : minNode.edges) {
if(!distanceMap.containsKey(edge.to)) { //通过边第一次发现某节点,将该节点放入map中
distanceMap.put(edge.to,edge.weight);
}else {
//minNode的值加上当前边的权值如果比edge.to自身值小,更新map中edge.to的值
distanceMap.put(edge.to,Math.min(distanceMap.get(edge.to),distanceMap.get(minNode)+edge.weight));
}
//当前节点已经处理完毕,加入到selectedNodes中
selectedNodes.add(minNode);
//将minNode更新为未选择过的节点中最小的那个
minNode = getMinAndUnelectedNode(distanceMap,selectedNodes);
}
}
return distanceMap;
}
public static Node getMinAndUnelectedNode(HashMap<Node,Integer> distanceMap,HashSet<Node> selectedNodes) {
int min = Integer.MAX_VALUE;
Node minNode = null;
for (Map.Entry<Node, Integer> entry : distanceMap.entrySet()) {
if(!selectedNodes.contains(entry.getKey())) {
min = Math.min(min, entry.getValue());
minNode = min == entry.getValue()?entry.getKey():minNode;
}
}
return minNode;
}