广度优先便利,或者广搜,见于二叉树求深度,走迷宫,字符串变换等

  • 通常会抽象出一个背景,类似开锁问题,每一个step对应一个状态,而进入到下一个step时会有多种选择
  • 具体某个状态就对应框架中的节点
  • 多种选择就是当前节点的所有邻接节点
#include<iostream>
#include<cstdio>
#include<queue>
#include<unordered_set>
using namespace std;

struct Node{

    // 任意类型节点,可以是图节点,树节点,迷宫节点,字符串中的字符等等
    int val;
    vector<Node*> adj;      // 该节点的所有邻接节点
};

// BFS:寻找从start到target的最短距离
int BFS(Node* start, Node* target){
    
    int step;           //  记录当前已扩展的步数
    queue<Node*> cache;  //  核心数据结构,存储当前step下所有节点
    unordered_set<Node*> visited;   // 记录已走过的节点,避免走回头路

    // start入队
    cache.push(start);
    visited.insert(start);

    // 遍历当前step下所有节点
    while(!cache.empty()){
        int sz = cache.size();  // 当前step下有多少个节点
        while(sz--){     // 分别处理每个节点
    
            Node* node = cache.front();
            cache.pop();

            // 判断是否为找到了target
            if(node == target)
                return step;
            
            // 如果不是target,则入队
            for(auto adjNode : node->adj){
                if(!visited.count(adjNode)){
                    cache.push(adjNode);
                    visited.insert(adjNode);
                }
            }
        }

        // 内while循环结束后,已经处理完当前step下所有节点了,因此
        step++;
    
    }

    return step;

}