1 概念
BFS 英文全称:Breadth-First-Search,广度优先搜索。
以下这段引用自百科: BFS属于一种盲目搜寻,目的是系统的展开并检查图中的所有节点,以找寻结果。
2 算法中的三种节点状态
2.1 待检验的节点(展开节点下得到的子节点)
该类节点会被存入一个先进先出的队列中
2.2 已被检验过的节点
该类节点会放入一个closed的容器中,比如说链表,队列等
2.3 未被检验的节点
该类节点会放入一个open的容器中,比如说链表,队列等
3 算法的实现逻辑
- 首先将根节点放入队列中
- 从队列中取出第一个节点,检验其是否为目标节点
    - 如果找到目标结果,则结束搜寻并回传结果
- 否则展开该节点下的所有子节点加入队列中
 
- 若队列为空,表示整张图或树都检查过了,未命中目标节点,返回空值
- 重复第二步
4 算法图形基本思路
以下图用三种颜色来区分算法中三种节点的状态

5 迷宫算法题
5.1 题目描述
定义一个二维数组如下:
int maze[5][5] = {
		0, 1, 0, 0, 0,
		0, 1, 0, 1, 0,
		0, 0, 0, 0, 0,
		0, 1, 1, 1, 0,
		0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
5.2 解题思路
在该题目中,我们的节点就是(x,y)形式的.
起点Vs为(0,0)
终点Vd为(4,4)
队列集合为Q={}
初始化所有节点为open容器,即绿色节点
- 起始节点Vs变成黄色,加入队列Q,Q={(0,0)}
- 取出队列Q的头一个节点Vn,Vn={0,0},Q={}
- 把Vn={0,0}染成红色,取出Vn所有相邻的绿色节点{(1,0)}
- 染成黄色,加入队列Q,Q={(1,0)},不包含终点(4,4)
- 取出队列Q的头一个节点Vn,Vn={1,0},Q={}
- 把Vn={1,0}染成红色,取出Vn所有相邻的绿色节点{(2,0)}
- 染成黄色,加入队列Q,Q={(2,0)},不包含终点(4,4)
- 取出队列Q的头一个节点Vn,Vn={2,0},Q={}
- 把Vn={2,0}染成红色,取出Vn所有相邻的绿色节点{(2,1), (3,0)}
- 染成黄色,加入队列Q,Q={(2,1), (3,0)},不包含终点(4,4)
- 取出队列Q的头一个节点Vn,Vn={2,1},Q={(3,0)}
- 把Vn={2,1}染成红色,取出Vn所有相邻的绿色节点{(2,2)}
- 染成黄色,加入队列Q,Q={(3,0), (2,2)},不包含终点(4,4)
- 持续下去,知道Vn的所有相邻的白色节点中包含了(4,4)
- 此时获得了答案
5.3 解题图示

5.4 解题代码
/**
 * 广度优先搜索
 * @param Vs 起点
 * @param Vd 终点
 */
bool BFS(Node& Vs, Node& Vd){
	queue<Node> Q;
	Node Vn, Vw;
	int i;
 
	//用于标记颜色当visit[i][j]==true时,说明节点访问过,也就是黑色
	bool visit[MAXL][MAXL];
 
	//四个方向
	int dir[][2] = {
		{0, 1}, {1, 0},
		{0, -1}, {-1, 0}
	};
 
	//初始状态将起点放进队列Q
	Q.push(Vs);
	visit[Vs.x][Vs.y] = true;//设置节点已经访问过了!
 
	while (!Q.empty()){//队列不为空,继续搜索!
		//取出队列的头Vn
		Vn = Q.front();
		Q.pop();
 
		for(i = 0; i < 4; ++i){
			Vw = Node(Vn.x+dir[i][0], Vn.y+dir[i][1]);//计算相邻节点
 
			if (Vw == Vd){//找到终点了!
				//把路径记录,这里没给出解法
				return true;//返回
			}
 
			if (isValid(Vw) && !visit[Vw.x][Vw.y]){
				//Vw是一个合法的节点并且为白色节点
				Q.push(Vw);//加入队列Q
				visit[Vw.x][Vw.y] = true;//设置节点颜色
			}
		}
	}
	return false;//无解
}
6 简化版广度优先搜索遍历
def BFS(graph, start, end):
	queue = []
	queue.append([start])
	visited.add(start)
	
	while queue:
		node = queue.pop()
		visited.add(node)
		
		process(node)
		nodes = generate_related_nodes(node)
		queue.push(nodes)
7 常见应用场景
- 查找连接组件
- 测试是否二分图
- 应用于计算机游戏中平面网格