DFS-BFS(深搜廣搜)原理及C++代碼實現


深搜和廣搜是圖很多算法的基礎,很多圖的算法都是從這兩個算法中啟發而來。

深搜簡單地說就是直接一搜到底,然后再回溯,再一搜到底,一直如此循環到沒有新的結點。

廣搜簡單地說就是一層一層的搜,像水的波紋一樣往外面擴散,擴散到最外層搜索也就完成了。

prim最小生成樹、Dijkstra單源最短路徑算法都使用了類似廣度優先搜索的思想。

拓撲排序就可以用深搜來實現,分解強連通分量也可以用深搜來實現(轉置圖加兩次深搜)

我們實現廣搜時需要用隊列來輔助我們進行。實現深搜時使用棧來輔助我們進行,所以顯而易見的用遞歸實現深搜也比較合適,因為遞歸本身就是棧存儲。

下面給出的廣搜是無向圖中,給定源結點的方法。

給出的深搜是有向圖中,未給出源結點的方法,且是非遞歸實現(遞歸實現相對比較簡單)。

代碼如下:(僅供參考)

 1 template<typename T>
 2 class Graph {
 3 private :
 4     struct Vertex {
 5         forward_list<T> vertex;
 6         bool color;
 7     };
 8     typedef unordered_map<T, Vertex> adjList;
 9     adjList Adj;
10 public :
11     void insertEdge(T x, T y) {Adj[x].vertex.push_front(y);}
12     void deleteEdge(T x, T y) {Adj[x].vertex.remove(y);}
13     void BFS(T s);
14     void DFS();
15 };
16 
17 template<typename T>
18 void Graph<T>::BFS(T s) {
19     vector<T> que;
20     for (auto i : Adj)
21         i.second.color = false;
22     Adj[s].color = true;
23     cout << s << ends;
24     que.insert(que.begin(), s);
25     while (!que.empty()) {
26         T u = que.back();
27         que.pop_back();
28         for (auto i : Adj[u].vertex)
29             if (Adj[i].color == false) {
30                 Adj[i].color = true;
31                 cout << i << ends;
32                 que.insert(que.begin(), i);
33             }
34     }
35 }
36 
37 template<typename T>
38 void Graph<T>::DFS() {
39     vector<T> stk;
40     for (auto i : Adj)
41         i.second.color = false;
42     for (auto u : Adj)
43         if (u.second.color == false) {
44             T v = u.first;
45             while (1) {
46                 if (Adj[v].color == false) {
47                     cout << v << ends;
48                     Adj[v].color = true;
49                 }
50                 auto p = Adj[v].vertex.begin();
51                 for ( ; p != Adj[v].vertex.end(); ++p)
52                     if (Adj[*p].color == false) {
53                         stk.push_back(v);
54                         v = *p;
55                         break;
56                     }
57                 if (p == Adj[v].vertex.end() && !stk.empty()) {
58                     v = stk.back();
59                     stk.pop_back();
60                 }
61                 else if (stk.empty()) break;
62             }
63         }
64 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM