什么是深度優先搜索(DFS)?
深度優先搜索屬於圖算法的一種,是一個針對圖和樹的遍歷算法,英文縮寫為DFS即Depth First Search。
深度優先搜索是圖論中的經典算法,利用深度優先搜索算法可以產生目標圖的相應拓撲排序表,利用拓撲排序表可以方便的解決很多相關的圖論問題,如最大路徑問題等等。
其過程簡要來說是對每一個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次。
深度優先的基本原則:按照某種條件往前試探搜索,如果前進中遭到失敗(正如老鼠遇到死胡同)則退回頭另選通路繼續搜索,直到找到滿足條件的目標為止。
下面是關於深度優先搜索的圖示:
算法描述:
可以看出,我們必須知道頂點是否已經被訪問過。
所以在具體實現時,我們可以用一個全局數組visited來記錄頂點是否被訪問過。
如果visited[i]的值為True,則頂點vi已經被訪問過,否則沒有被訪問。
DFS背后的想法是盡可能深入到圖形中,並在沒有任何未訪問的相鄰頂點的情況下回溯到頂點。
遞歸地描述/實現算法非常容易:我們在一個頂點開始搜索。
在訪問頂點之后,我們進一步對我們之前沒有訪問過的每個相鄰頂點執行DFS。
這樣我們就可以訪問從起始頂點可到達的所有頂點。
算法實現:
int n; vector<bool> visited; void dfs(int v) { visited[v] = true; for () { if (!visited[u]) dfs(u); } }
DFS的運用:
走迷宮:
給一個n行m列的2維的迷宮,'S'表示迷宮的起點,'T'表示迷宮的終點,'#'表示不能通過的點,'.' 表示可以通過的點。 你需要從'S'出發走到'T',每次只能上下左右走動,並且只能進入能通過的點,每個點只能通過一次。現在要求你求出有多少種通過迷宮的的方案。
輸入格式
第一行輸入n,m(1≤n,m≤10)表示迷宮大小。接下來輸入n 行字符串表示迷宮。
輸出格式
輸出通過迷宮的方法數。
樣例輸入
2 3
S.#
..T
樣例輸出
2
代碼實現

1 #include <iostream> 2 #include<cmath> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include <algorithm> 7 using namespace std; 8 typedef long long ll; 9 10 //調用Enter函數和DFS函數 11 void Enter(); 12 void DFS(int i,int j); 13 int n,m,x,y,way;//n,m記錄迷宮大小,x,y記錄'S'的地址, way記錄路徑的數量 14 char Maze[10][10];//存儲迷宮 15 int Flag[10][10];//在DFS函數中標記 0為沒經過,1為已經經過 16 17 18 int main() 19 { 20 int i,j; 21 cin>>n>>m; 22 for(i=0;i<n;i++) 23 { 24 for(j=0;j<m;j++) 25 { 26 cin>>Maze[i][j]; 27 } 28 } 29 Enter();//查找入口'S'位置,記錄其坐標x,y位置 30 DFS(x,y);//用深度優先搜索函數統計其路徑 31 cout<<way<<endl; 32 33 return 0; 34 } 35 36 void Enter() 37 { 38 for(int i=0;i<n;i++) 39 { 40 for(int j=0;j<m;j++) 41 { 42 if(Maze[i][j]='S') 43 { 44 x=i; 45 y=j; 46 return; 47 } 48 } 49 } 50 } 51 52 void DFS(int i,int j) 53 { 54 if(i<0||j<0||i>=n||j>=m) 55 { 56 return; 57 } 58 if(Maze[i][j]=='T') 59 { 60 way++; 61 return; 62 } 63 else if(Maze[i][j]=='#') 64 { 65 return; 66 } 67 else 68 { 69 if((Maze[i][j]=='.'||Maze[i][j]=='S')&&Flag[i][j]==0) 70 { 71 Flag[i][j]=1; 72 //迭代的過程 73 DFS(i,j+1);//向上遍歷 74 DFS(i+1,j);//向右遍歷 75 DFS(i,j-1);//向下遍歷 76 DFS(i-1,+j);//向左遍歷 77 78 Flag[i][j]=0; 79 } 80 } 81 }