DFS與BFS的區別、用法、詳解?
阿新 • • 發佈:2019-01-09
寫在最前的三點:
1、所謂圖的遍歷就是按照某種次序訪問圖的每一頂點一次僅且一次。
2、實現bfs和dfs都需要解決的一個問題就是如何儲存圖。一般有兩種方法:鄰接矩陣和鄰接表。這裡為簡單起
見,均採用鄰接矩陣儲存,說白了也就是二維陣列。
3、本文章的小測試部分的測試例項是下圖:
一、深度優先搜尋遍歷
1、從頂點v出發深度遍歷圖G的演算法
① 訪問v
② 依次從頂點v未被訪問的鄰接點出發深度遍歷。
2、一點心得:dfs演算法最大特色就在於其遞迴特性,使得演算法程式碼簡潔。但也由於遞迴使得演算法難以理解,原因
在於遞迴使得初學者難以把握程式執行到何處了!一點建議就是先學好遞迴,把握函式呼叫是的種種。
3、演算法程式碼:
- #include<iostream>
- usingnamespace std;
- int a[11][11];
- bool visited[11];
- void store_graph() //鄰接矩陣儲存圖
- {
- int i,j;
- for(i=1;i<=10;i++)
- for(j=1;j<=10;j++)
- cin>>a[i][j];
- }
- void dfs_graph() //深度遍歷圖
- {
- void dfs(int v);
-
memset(visited,false
- for(int i=1;i<=10;i++) //遍歷每個頂點是為了防止圖不連通時無法訪問每個頂點
- if(visited[i]==false)
- dfs(i);
- }
- void dfs(int v) //深度遍歷頂點
- {
- int Adj(int x);
- cout<<v<<" "; //訪問頂點v
- visited[v]=true;
- int adj=Adj(v);
- while(adj!=0)
- {
-
if
- dfs(adj); //遞迴呼叫是實現深度遍歷的關鍵所在
- adj=Adj(v);
- }
- }
- int Adj(int x) //求鄰接點
- {
- for(int i=1;i<=10;i++)
- if(a[x][i]==1 && visited[i]==false)
- return i;
- return 0;
- }
- int main()
- {
- cout<<"初始化圖:"<<endl;
- store_graph();
- cout<<"dfs遍歷結果:"<<endl;
- dfs_graph();
- return 0;
- }
4、小測試
二、廣度優先搜尋遍歷
1、從頂點v出發遍歷圖G的演算法買描述如下:
①訪問v
②假設最近一層的訪問頂點依次為vi1,vi2,vi3...vik,則依次訪問vi1,vi2,vi3...vik的未被訪問的鄰接點
③重複②知道沒有未被訪問的鄰接點為止
2、一點心得:bfs演算法其實就是一種層次遍歷演算法。從演算法描述可以看到該演算法要用到佇列這一資料結構。我這
裡用STL中的<queue>實現。該演算法由於不是遞迴演算法,所以程式流程是清晰的。
3、演算法程式碼:
- #include<iostream>
- #include<queue>
- usingnamespace std;
- int a[11][11];
- bool visited[11];
- void store_graph()
- {
- for(int i=1;i<=10;i++)
- for(int j=1;j<=10;j++)
- cin>>a[i][j];
- }
- void bfs_graph()
- {
- void bfs(int v);
- memset(visited,false,sizeof(visited));
- for(int i=1;i<=10;i++)
- if(visited[i]==false)
- bfs(i);
- }
- void bfs(int v)
- {
- int Adj(int x);
- queue<int> myqueue;
- int adj,temp;
- cout<<v<<" ";
- visited[v]=true;
- myqueue.push(v);
- while(!myqueue.empty()) //佇列非空表示還有頂點未遍歷到
- {
- temp=myqueue.front(); //獲得佇列頭元素
- myqueue.pop(); //頭元素出對
- adj=Adj(temp);
- while(adj!=0)
- {
- if(visited[adj]==false)
- {
- cout<<adj<<" ";
- visited[adj]=true;
- myqueue.push(adj); //進對
- }
- adj=Adj(temp);
- }
- }
- }
- int Adj(int x)
- {
- for(int i=1;i<=10;i++)
- if(a[x][i]==1 && visited[i]==false)
- return i;
- return 0;
- }
- int main()
- {
- cout<<"初始化圖:"<<endl;
- store_graph();
- cout<<"bfs遍歷結果:"<<endl;
- bfs_graph();
- return 0;
- }
4、小測試: