package com.zy.acs.manager.common.utils; import java.util.*; /** * Breadth-First Search * 1.可用于计算最短路径 或者 快速反推二叉树的根节点 * https://www.bilibili.com/video/BV1Ks411575U/?vd_source=6f04e61f1b57e41e7986c65388d892fb * 2.如果连接有权重,那么把Queue变成PriorityQueue => Dijkstra * https://www.bilibili.com/video/BV1ts41157Sy/?spm_id_from=333.999.0.0&vd_source=6f04e61f1b57e41e7986c65388d892fb */ public class BFS { private final Map> graph; private final Set visited = new HashSet<>(); // 可以通过BFS扫描节点连接关系,来获取节点的最近路径的父节点hash表 private final Map parent = new HashMap<>(); public BFS(Map> graph) { this.graph = graph; } public List execute(String startNode) { if (null == graph) { throw new RuntimeException("the graph was empty"); } List list = new ArrayList<>(); Queue queue = new LinkedList<>(); queue.add(startNode); visited.add(startNode); parent.put(startNode, null); while (queue.size() > 0) { String node = queue.poll(); List nears = graph.get(node); for (String near : nears) { if (!visited.contains(near)) { queue.offer(near); visited.add(near); parent.put(near, node); } } list.add(node); } return list; } public static void main(String[] args) { Map> graph = new HashMap<>(); graph.put("A", new ArrayList(){{add("B");add("C");}}); graph.put("B", new ArrayList(){{add("A");add("C");add("D");}}); graph.put("C", new ArrayList(){{add("A");add("B");add("D");add("E");}}); graph.put("D", new ArrayList(){{add("B");add("C");add("E");add("F");}}); graph.put("E", new ArrayList(){{add("C");add("D");}}); graph.put("F", new ArrayList(){{add("D");}}); BFS bfs = new BFS(graph); bfs.execute("E"); String endNode = "B"; List shortestPath = new ArrayList<>(); while (endNode != null) { shortestPath.add(endNode); endNode = bfs.parent.get(endNode); } Collections.reverse(shortestPath); System.out.println("shortestPath: " + shortestPath); } }