BFS算法解析

深度优先搜索得到的路径不仅取决于图的结构,还取决于图的表示和递归调用的性质。我们很自然的还经常对下面的这些问题感兴趣。

单点最短路径。“从s到给定目的顶点v是否存在一条路径?如果有,找出其中最短的那条(所含边数最少)。”

解决这个问题的经典方法叫做广度优先搜索(BFS)。

要找到从s到v的最短路径,从s开始,在所有由一条边就可以到达的顶点中寻找v,如果找不到我们就继续在与s距离两条边的所有顶点中寻找v,如此一直进行。深度优先搜索就好像是一个人在走迷宫,广度优先搜索则好像是一组人在一起朝各个方向走这座迷宫,每个人都有自己的绳子。当出现新的岔路时,可以假设一个探索者可以分裂为更多的人来搜索它们,当两个探索者相遇时,会合二为一(并继续使用先到达者的绳子)。

在程序中,在搜索一幅图时会遇到有多条边需要遍历的情况时,我们会选择其中一条并将其他通道留到以后在继续搜索。在深度优先搜索中,我们使用了一个可以下压的栈。使用LIFO的规则来描述压栈和走迷宫时先探索相邻的通道类似。从有待搜索的通道中选择最晚遇到过的那条。在广度优先搜索中,我们希望按与起点的距离的顺序来遍历所有顶点,看起来这种顺序很容易实现:使用FIFO队列来代替栈即可。我们将从有待搜索的通道中选择最早遇到的那条。

下面算法实现了广度优先搜索算法。它使用了一个队列来保存所有已经被标记过但其邻接表还未被检查过的顶点。先讲起点加入队列,然后重复一下步骤直到队列为空:

取队列中的下一个顶点v并标记它;

将与v相邻的所有未被标记过的顶点加入队列。

public class BreadthFirstSearch {

	private boolean[] marked; 

	public BreadthFirstSearch(Graph G, int s) {
		marked = new boolean[G.V()];
		bfs(G, s);
	}

	private void bfs(Graph G, int s) {
		Queue<Integer> queue = new Queue<>();
		marked[s] = true; // 标记起点
		queue.enqueue(s);
		while (!queue.isEmpty()) {
			int v = queue.dequeue();
			for (int w : G.adj(v)) {
				if (!marked[w]) {
					marked[w] = true;
					queue.enqueue(w);
				}
			}
		}
	}
}
bfs算法不是递归的。不像递归中隐式使用的栈,它显示使用了一个队列。

对于从s可达的任意顶点v,广度优先搜索都能找到一条从s到v的最短路径(没有其他从s到v的路径所含的边比这条路径更少)。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值