通俗理解BFS和DFS,附基本模板
阿新 • • 發佈:2018-12-11
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 boolmark[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 return0; 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 }