# 利用广度优先遍历(BFS)计算最短路径 - Java实现

``````    BFS: From [North Gate] to [Canteen]:
North Gate
Square
Canteen``````

``````public interface Algorithm {
/** * 执行算法 */
void perform(Graph g, String sourceVertex);

/** * 得到路径 */
Map<String, String> getPath();
}``````

``````/** * (无向)图 */
public class Graph {
// 图的起点
private String firstVertax;

// 邻接表
private Map<String, List<String>> adj = new HashMap<>();

// 遍历算法
private Algorithm algorithm;

public Graph(Algorithm algorithm) {
this.algorithm = algorithm;
}

/** * 执行算法 */
public void done() {
algorithm.perform(this, firstVertax);
}

/** * 得到从起点到{@code vertex}点的最短路径 * @param vertex * @return */
public Stack<String> findPathTo(String vertex) {
Stack<String> stack = new Stack<>();

Map<String, String> path = algorithm.getPath();
for (String location = path.get(vertex) ; false == location.equals(firstVertax) ; location = path.get(location)) {
stack.push(location);
}
stack.push(firstVertax);

return stack;
}

/** * 添加一条边 */
public void addEdge(String fromVertex, String toVertex) {
if (firstVertax == null) {
firstVertax = fromVertex;
}

}

/** * 添加一个顶点 */
}

}
}``````

``````public Graph(Algorithm algorithm) {
this.algorithm = algorithm;
}``````

``````// 邻接表
private Map<String, List<String>> adj = new HashMap<>();``````

``````/** * 封装BFS算法 */
public class BroadFristSearchAlgorithm implements Algorithm {
// 保存已经访问过的地点
private List<String> visitedVertex;
// 保存最短路径
private Map<String, String> path;

@Override
public void perform(Graph g, String sourceVertex) {
if (null == visitedVertex) {
visitedVertex = new ArrayList<>();
}
if (null == path) {
path = new HashMap<>();
}

BFS(g, sourceVertex);
}

@Override
public Map<String, String> getPath() {
return path;
}

private void BFS(Graph g, String sourceVertex) {
// 标记起点
// 起点入列

while (false == queue.isEmpty()) {
String ver = queue.poll();

for (String v : toBeVisitedVertex) {
if (false == visitedVertex.contains(v)) {
path.put(v, ver);
}
}
}
}
}``````

BFS算法描述：
1. 将起点标记为已访问并放入队列。
2. 从队列中取出一个顶点，得到与该顶点相通的所有顶点。
3. 遍历这些顶点，先判断顶点是否已被访问过，如果否，标记该点为已访问，记录当前路径，并将当前顶点入列。
4. 重复2、3，直到队列为空。

``````String[] vertex = {"North Gate", "South Gate", "Classroom", "Square", "Toilet", "Canteen"};
Edge[] edges = {
new Edge("North Gate", "Classroom"),
new Edge("North Gate", "Square"),
new Edge("Classroom", "Toilet"),
new Edge("Square", "Toilet"),
new Edge("Square", "Canteen"),
new Edge("Toilet", "South Gate"),
new Edge("Toilet", "South Gate"),
};``````
``````@Test
public void testBFS() {
Graph g = new Graph(new BroadFristSearchAlgorithm());