5-1 图的广度优先思想
广度优先搜索
(
BFS
,
Breadth First Search
)是一个分层的搜索过程,没有回退过程,是非递归的。
BFS
算法的思想是:对一个无向连通图,在访问图中某一起始顶点
v
后,由
v
出发,依次访问 v 的所有未访问过的邻接顶点 w
1
,
w
2
,
w
3
, …
w
t;然后再顺序访问 w1,
w
2
,
w
3
, …
w
t
的所有还未访问过的邻接顶点;再从这些访问过的顶点出发,再访问它们的所有
还未访问过的邻接顶点,……,如此直到图中所有顶点都被访问到为止。
接下来以图
2.13(a)
所示的无向连通图为例解释
BFS
搜索过程。假设在多个未访问过的邻接顶点中进行选择时,按顶点序号从小
到大的顺序进行选择,比如顶点 A 有 3
个邻接顶点,即
B
、
E和 D,则按 B
、
D
和
E
的顺序依次访问。
对图
2.13(a)
所示的无向连通图,采用
BFS
思想搜索的过程为:
1)
访问顶点
A
,这是第一层;
2)
访问顶点
A
的
3
个邻接顶点
B
、
D
和
E
,这是第二层;
3)
访问顶点
B
的未访问过的邻接顶点(即顶点
C
),访问顶点
D
的未访问过的邻接顶点(即
第
2
章 图的遍历与活动网络问题
顶点 F
),顶点
E
没有未访问过的邻接顶点,这是第三层;
4)
访问顶点
C
的未访问过的邻接顶点(即顶点
G
),访问顶点
F
的未访问过的邻接顶点(即顶点 H),这是第四层;
5)
顶点
G
没有未访问过的邻接顶点,访问顶点
H
的未访问过的邻接顶点(即顶点
I
),这是第五层。
至此,
BFS
搜索完毕。图
(a)
中各顶点旁的数字表示
BFS
过程中各顶点的访问顺序,图
(b)
为
广度优先搜索生成树
:用访问
n
个顶点时经过的
n
-1
条边,将
n
个顶点连接成一棵树。
5-2 图的 BFS 的实现
二叉树是比较标准的一种结构,而图相对没有那么规范。图与二叉树两者的广度优先遍历都是使用队列实现,但是稍微不同的一点是:图需要记录结点是否已经遍历过。
图为:
7 7
0 1
0 2
1 3
1 4
2 3
2 6
5 6
package graphDFS;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
public class GraphBFS {
private Graph graph;
private boolean[] visited;
private ArrayList<Integer> order = new ArrayList<>();
public GraphBFS(Graph graph) {
this.graph = graph;
this.visited = new boolean[graph.V()];
for (int v = 0; v < graph.V(); v++) { //循环判断,防止出现图不连通的情况
if (!visited[v]) {
bfs(v);
}
}
}
private void bfs(int s) {
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(s);
visited[s] = true;
while(!queue.isEmpty()) {
int v = queue.remove(); // 获取队首元素
order.add(v);
for (int w: graph.adj(v)) {
if (!visited[w]) {
queue.add(w);
visited[w] = true;
}
}
}
}
public Iterable<Integer> order(){
return order;
}
public static void main(String[] args) {
Graph graph = new Graph("g5.txt");
GraphBFS graphBFS = new GraphBFS(graph);
System.out.println(graphBFS.order());
}
}
项目推荐:
Java微服务实战296集大型视频-谷粒商城【附代码和课件】