通俗理解BFS和DFS,附基本模板
1.BFS(宽度优先搜索):使用队列来保存未被检测的节点,按照宽度优先的顺序被访问和进出队列
打个比方:(1)类似于树的按层次遍历
(2)你的眼镜掉在了地上,你趴在地上,你总是先摸离你最近的地方,如果没有,再摸远一点的地方……
1 BFS算法: 2 3 通常用队列(先进先出,FIFO)实现 4 5 初始化队列Q; 6 Q = {起点s}; 7 标记s为已访问; 8 while(Q非空) 9 { 10 取Q队首元素u; 11 u出队; 12 if(u==目标状态) 13 { 14 …… 15 } 16 else 17 { 18 所有与u相邻且未被访问的点进入队列; 19 标记u为已访问; 20 } 21 }
1 //BFS算法框架 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<algorithm> 7 using namespace std; 8 9 const int maxn = 100; 10 bool mark[maxn][maxn]; //访问标记 11 int go[4][2] = {0,-1,1,0,0,1,-1,0}; //方向向量 12 13 struct State 14 { 15 int x,y; //坐标位置 16 int step; //搜索步数记录 17 }; 18 19 State maze[maxn]; 20 21 bool CheckState(State s) 22 { 23 if(!mark[s.x][s.y]&&(边界条件满足)) //符合条件 24 return 1; 25 else //不符合条件 26 return 0; 27 } 28 29 void BFS(State st) 30 { 31 queue<State> q; 32 State now,next; 33 st.step = 0; //步数清零; 34 q.push(st); //入队; 35 mark[st.x][st.y] = 1; //访问标记 36 while(!q.empty()) 37 { 38 now = q.front(); //取队首元素进行拓展 39 q.pop(); //队首元素出队; 40 if(now == 目标状态) //出现目标状态,此时的step为最小值,做做相关处理后退出即可; 41 { 42 ……; 43 return ; 44 } 45 //如果没有到目标状态: 46 else 47 { 48 for(int i=0;i<4;i++) 49 { 50 next.x = now.x + go[i][0];//按照规则生成下一个状态 51 next.y = now.y + go[i][1]; 52 if(CheckState(next)) //如果状态满足条件则入队; 53 { 54 next.step = now.step + 1; 55 q.push(next); 56 } 57 } 58 } 59 return ; 60 } 61 } 62 63 int main() 64 { 65 ……; 66 BFS(); 67 ……; 68 return 0; 69 }
DFS (深度优先搜索):一直往下搜,知道找到解或者走不下去为止
打个比方:(1)类似于树的先根遍历
(2)类似于你在走迷宫,你不能分身来站在每个走过的位置,所以,你只能不撞南墙不回头。
1 DFS: 2 3 使用栈来保存未被检测的节点, 4 节点按照深度优先的次序被访问并依次压入栈中,并已相反的次序出栈进行新的检测。 5 6 DFS(dep,……)//dep代表目前DFS的深度 7 { 8 if(找到解||走不下去了) 9 { 10 ……; 11 return; 12 } 13 else 14 { 15 枚举下一种情况; 16 DFS(dep+1,……); 17 } 18 }
1 //DFS算法框架: 2 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 using namespace std; 7 8 const int maxn = 100; 9 bool mark[maxn][maxn]; //访问标记 10 int maze[maxn][maxn]; //坐标范围 11 int go[4][2] = {0,-1,1,0,0,1,-1,0}; //方向向量 12 13 bool CheckState(int x,int y) 14 { 15 if(!mark[x][y]&&……) //满足条件 16 return 1; 17 else //与约束条件冲突 18 return 0; 19 } 20 21 void DFS(int x,int y) 22 { 23 mark[x][y] = 1; //标记该节点被访问过 24 if(maze[x][y] == G) //出现目标状态G 25 { 26 …… //做相应处理 27 return ; 28 } 29 else 30 { 31 for(int i=0;i<4;i++) 32 if(CheckState(x+go[i][0],y+go[i][1])) //按照规则生成下一个节点 33 DFS(x+go[i][0],y+go[i][1]); 34 } 35 return ; //如果没有下层搜索点,则回溯; 36 } 37 38 int main() 39 { 40 ……; 41 return 0; 42 }