算法介绍:
广度优先搜索(BFS,Breadth-First Search)是一种用于遍历或搜索树或图的算法。该算法从根开始,然后遍历所有相邻的节点,然后对每个相邻节点进行同样的操作,直到遍历完所有节点。
实现原理:
- 创建一个名为
bfs
的函数,接受两个参数:起始顶点i
和邻接矩阵G
。 - 创建一个
visited
数组,用于标记已访问的顶点。创建一个队列queue
,用于存储待访问的顶点。 - 首先,将起始顶点
i
标记为已访问,并将其入队。 - 当队列不为空时,执行以下操作: a. 从队列中出队一个顶点
v
。 b. 遍历G
矩阵,检查与v
相邻的所有顶点w
。如果w
未被访问过且G[v][w]
为1,则将w
标记为已访问,并将其入队。 - 当队列为空时,遍历结束。
特点:
- 顺序访问:BFS按层次顺序访问节点,同一层的节点被访问的顺序取决于它们在队列中的顺序。
- 最短路径:在无权图中,BFS可以用来找到两个节点之间的最短路径。
- 空间消耗:需要额外的空间来存储队列,空间复杂度为O(V),其中V是图中顶点的数量。
- 时间复杂度:对于无向图,BFS的时间复杂度通常是O(V+E),其中E是边的数量,因为每个节点和边最多被访问一次。
应用场景:
- 寻找最短路径:在无权图中寻找两个节点间的最短路径。
- 判断连通性:判断图是否连通,以及计算连通分量的数量。
- 拓扑排序:在有向无环图(DAG)中进行拓扑排序。
- 游戏和迷宫:解决游戏中寻找最短路径的问题,比如走迷宫。
注意:
- 使用一个布尔数组或哈希表来记录哪些节点已经被访问,以避免重复访问。
- 在实现时,通常会用到队列数据结构来维持待访问节点的顺序。
以下为完整程序代码(包含测试用例):
import java.util.LinkedList;
import java.util.Queue;
//广度优先遍历
//邻接矩阵
public class BFS_2 {
// BFS函数
// i 起始结点
// G 邻接数组
public static void bfs(int i, int G[][]) {
boolean[] visited = new boolean[G.length];// 标记数组
Queue<Integer> queue = new LinkedList<Integer>();// 创建一个空队列
// Stack<Integer> stack = new Stack<Integer>(); //创建一个空栈BFS_2.java
System.out.println(i);// 打印该结点信息
visited[i] = true;// 将该结点标记为已访问
queue.add(i);// 入队
while (!queue.isEmpty()) {// 判断队列是否为空
int v = queue.poll();// 出队,并记录结点信息
for (int w = 0; w < G.length; w++) {
if (visited[w] == false && G[v][w] == 1) {
System.out.println(w);// 打印该结点信息
visited[w] = true;// 将该结点标记为已访问
queue.add(w);// 入队
}
}
}
}
public static void main(String[] args) {
int[][] G = {
{ 0, 1, 1, 0, 1 },
{ 1, 0, 0, 1, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 0, 0, 1 },
{ 1, 1, 1, 1, 0 }
};// 邻接矩阵
bfs(2, G);
}
}