zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    java类继承总结一 父类类型与子类类型之间的转化问题(转)
    将子类对象引用赋值给超类对象 JAVA 编译时多态性
    JAVA访问控制变量、类变量、类方法
    java传递是引用的拷贝,既不是引用本身,更不是对象
    JAVA的StringBuffer类
    (文件名.JAVA)的文件名只能与该文件中的public类的名称一致
    类变量(静态变量)的值不能被构造函数改写
    程序启动的顺序以及实例变量相互赋值、传递拷贝的理解
    MySQL选择合适的字符集
    MySQL日期类型选择
  • 原文地址:https://www.cnblogs.com/yxsrt/p/12249928.html
Copyright © 2011-2022 走看看