一、介绍
图的DFS(深度优先搜索)与BFS(广度优先搜索)是图的两种遍历方式。
主要区别在于当到达图中的一个顶点后,DFS直接到达其中的一个(未遍历过的)顶点,之后再以这个新的顶点为基点重复上面的操作;而BFS到达图中的一个顶点后,会先遍历顶点周围的所有(未遍历过的)顶点,然后在以其中的一个顶点为基点,重复上面的操作。
举个简单的例子:
如果分别用DFS和BFS进行遍历(以A为起点):
DFS:A B D E C (一条路走到头)
BFS:A B C D E (先把A的周围走完,接着走完B和C的周围)
这篇文章将进行BFS的分析,前一篇文章分析DFS:link
二、图的建立
2.1建立图类
- 使用邻接矩阵保存图的信息。
- 为了给每个顶点起名字,使用了两组map集合使顶点的名字与邻接矩阵的数字一一对应。
- 用boolean型数组记录某节点是否被访问过。
代码:
class graph{
int vertexNum;//顶点数
int edgeNum;//边数
int[][] adjacentMatrix;//邻接矩阵
boolean[] isVisited;//各顶点是否被访问
Map<Character,Integer> nameToNum;
Map<Integer,Character> numToName;
int index;//顶点名称的下标
//构造函数
graph(int vertexnum, int edgenum){
vertexNum = vertexnum;
edgeNum = edgenum;
adjacentMatrix = new int[vertexNum][vertexNum];
nameToNum = new HashMap<>();
numToName = new HashMap<>();
isVisited = new boolean[vertexnum];
}
//顶点名称
public void addVertexName(char vertex){
nameToNum.put(vertex,index);
index++;
}
//反转顶点和其索引的对应关系
public void invertNameToNum(){
Set<Character> chs = nameToNum.keySet();
for (Character c : chs) {
numToName.put(nameToNum.get(c),c);
}
}
//打印两个map
public void printMap(){
System.out.println("name to num:");
Set<Character> chs = nameToNum.keySet();
for (Character c : chs) {
System.out.println(c + "->" + nameToNum.get(c));
}
System.out.println();
System.out.println("num to name:");
Set<Integer> ins = numToName.keySet();
for (Integer in : ins) {
System.out.println(in+"->"+ numToName.get(in));
}
}
//添加边
public void addEdge(char vertex1, char vertex2, int weight){
adjacentMatrix[nameToNum.get(vertex1)][nameToNum.get(vertex2)] = weight;
adjacentMatrix[nameToNum.get(vertex2)][nameToNum.