1. 程式人生 > >DFS與BFS的區別、用法、詳解?

DFS與BFS的區別、用法、詳解?

寫在最前的三點:

1、所謂圖的遍歷就是按照某種次序訪問圖的每一頂點一次僅且一次

2、實現bfs和dfs都需要解決的一個問題就是如何儲存圖。一般有兩種方法:鄰接矩陣和鄰接表。這裡為簡單起

見,均採用鄰接矩陣儲存,說白了也就是二維陣列。

3、本文章的小測試部分的測試例項是下圖:

一、深度優先搜尋遍歷

1、從頂點v出發深度遍歷圖G的演算法

① 訪問v

② 依次從頂點v未被訪問的鄰接點出發深度遍歷。

2、一點心得:dfs演算法最大特色就在於其遞迴特性,使得演算法程式碼簡潔。但也由於遞迴使得演算法難以理解,原因

在於遞迴使得初學者難以把握程式執行到何處了!一點建議就是先學好遞迴,把握函式呼叫是的種種。

3、演算法程式碼:

  1. #include<iostream>
  2. usingnamespace std;  
  3. int a[11][11];  
  4. bool visited[11];  
  5. void store_graph()  //鄰接矩陣儲存圖
  6. {  
  7.     int i,j;  
  8.     for(i=1;i<=10;i++)  
  9.         for(j=1;j<=10;j++)  
  10.             cin>>a[i][j];  
  11. }  
  12. void dfs_graph()    //深度遍歷圖
  13. {  
  14.     void dfs(int v);  
  15.     memset(visited,false
    ,sizeof(visited));  
  16.     for(int i=1;i<=10;i++)  //遍歷每個頂點是為了防止圖不連通時無法訪問每個頂點
  17.         if(visited[i]==false)  
  18.             dfs(i);  
  19. }  
  20. void dfs(int v)  //深度遍歷頂點
  21. {  
  22.     int Adj(int x);  
  23.     cout<<v<<" ";  //訪問頂點v
  24.     visited[v]=true;  
  25.     int adj=Adj(v);  
  26.     while(adj!=0)  
  27.     {  
  28.         if
    (visited[adj]==false)     
  29.             dfs(adj);      //遞迴呼叫是實現深度遍歷的關鍵所在
  30.         adj=Adj(v);  
  31.     }  
  32. }  
  33. int Adj(int x)   //求鄰接點
  34. {  
  35.     for(int i=1;i<=10;i++)  
  36.         if(a[x][i]==1 && visited[i]==false)  
  37.             return i;  
  38.     return 0;  
  39. }  
  40. int main()  
  41. {  
  42.     cout<<"初始化圖:"<<endl;  
  43.     store_graph();  
  44.     cout<<"dfs遍歷結果:"<<endl;  
  45.     dfs_graph();  
  46.     return 0;  
  47. }  

4、小測試

二、廣度優先搜尋遍歷

1、從頂點v出發遍歷圖G的演算法買描述如下:

①訪問v

②假設最近一層的訪問頂點依次為vi1,vi2,vi3...vik,則依次訪問vi1,vi2,vi3...vik的未被訪問的鄰接點

③重複②知道沒有未被訪問的鄰接點為止

2、一點心得:bfs演算法其實就是一種層次遍歷演算法。從演算法描述可以看到該演算法要用到佇列這一資料結構。我這

裡用STL中的<queue>實現。該演算法由於不是遞迴演算法,所以程式流程是清晰的。

3、演算法程式碼:

  1. #include<iostream>
  2. #include<queue>    
  3. usingnamespace std;  
  4. int a[11][11];  
  5. bool visited[11];  
  6. void store_graph()    
  7. {  
  8.     for(int i=1;i<=10;i++)  
  9.         for(int j=1;j<=10;j++)  
  10.             cin>>a[i][j];  
  11. }  
  12. void bfs_graph()      
  13. {  
  14.     void bfs(int v);  
  15.     memset(visited,false,sizeof(visited));  
  16.     for(int i=1;i<=10;i++)    
  17.         if(visited[i]==false)  
  18.             bfs(i);  
  19. }  
  20. void bfs(int v)  
  21. {  
  22.     int Adj(int x);  
  23.     queue<int> myqueue;  
  24.     int adj,temp;  
  25.     cout<<v<<" ";  
  26.     visited[v]=true;  
  27.     myqueue.push(v);  
  28.     while(!myqueue.empty())    //佇列非空表示還有頂點未遍歷到
  29.     {  
  30.         temp=myqueue.front();  //獲得佇列頭元素
  31.         myqueue.pop();         //頭元素出對
  32.         adj=Adj(temp);  
  33.         while(adj!=0)  
  34.         {  
  35.             if(visited[adj]==false)  
  36.             {  
  37.                 cout<<adj<<" ";  
  38.                 visited[adj]=true;  
  39.                 myqueue.push(adj);   //進對
  40.             }  
  41.             adj=Adj(temp);  
  42.         }  
  43.     }  
  44. }  
  45. int Adj(int x)     
  46. {  
  47.     for(int i=1;i<=10;i++)  
  48.         if(a[x][i]==1 && visited[i]==false)  
  49.             return i;  
  50.     return 0;  
  51. }  
  52. int main()  
  53. {  
  54.     cout<<"初始化圖:"<<endl;  
  55.     store_graph();  
  56.     cout<<"bfs遍歷結果:"<<endl;  
  57.     bfs_graph();  
  58.     return 0;  
  59. }  

4、小測試: