• 图论算法之DFS与BFS


    • 概述(总)
    DFS是算法中图论部分中最基本的算法之一。对于算法入门者而言,这是一个必须掌握的基本算法。它的算法思想可以运用在很多地方,利用它可以解决很多实际问题,但是深入掌握其原理是我们灵活运用它的关键所在。
    • 含义特点
    DFS即深度优先搜索,有点类似广度优先搜索,也是对一个连通图进行遍历的算法。它的思想是从一个顶点V0开始,沿着一条路一直走到底,如果发现不能到达目标解,那就返回到上一个节点,然后从另一条路开始走到底,这种尽量往深处走的概念即是深度优先的概念。
    由于用到递归,当节点特别多且深度很大的时候,可能会发生栈溢出。解决办法是将递归改为非递归,自行编写栈。
    BFS即广度优先搜索(也称宽度优先搜索),是连通图的一种遍历策略。因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域,故得名。 一般可以用它做什么呢?一个最直观经典的例子就是走迷宫,我们从起点开始,找出到终点的最短路程,很多最短路径算法就是基于广度优先的思想成立的。
    • 应用场景
    • dfs
    1. 连通分量
    连通分量:任意两点可互达的图。
    求无向图的连通分量:O(n)
    1. 二分图判定
    二分图:每条边的两个节点分别着不同的两种颜色。
    判断一个图是否是二分图:O(n)
    1. 二叉树的递归遍历
    • bfs
    1. 求割顶和桥
    割顶:对于无向图G,如果删除某点u后,连通分量数目增加,则u即割顶。
    桥:对于无向图G,如果删除某点边e后,连通分量数目增加,则e即桥。
    求所有的图中的割顶和桥:
    方式一:尝试删除每个节点,用dfs判断连通分量是否增加。时间复杂度:O(n(n+m))。
    方式二:给每个节点记录两个时间戳,深入挖掘dfs。时间复杂度:O(n+m)。
     

      2.二叉树的层次遍历

    • 代码实现
    /**
    * DFS核心伪代码
    * 前置条件是visit数组全部设置成false
    * @param n 当前开始搜索的节点
    * @param d 当前到达的深度
    * @return 是否有解
    */
    bool DFS(Node n, int d){
    if (isEnd(n, d)){//一旦搜索深度到达一个结束状态,就返回true
    return true;
    }
    for (Node nextNode in n){//遍历n相邻的节点nextNode
    if (!visit[nextNode]){//
    visit[nextNode] = true;//在下一步搜索中,nextNode不能再次出现
    if (DFS(nextNode, d+1)){//如果搜索出有解
    //做些其他事情,例如记录结果深度等
    return true;
    }
    //重新设置成false,因为它有可能出现在下一次搜索的别的路径中
    visit[nextNode] = false;
    }
    }
    return false;//本次搜索无解
    }
    /**
    * 广度优先搜索
    * @param Vs 起点
    * @param Vd 终点
    */
    bool BFS(Node& Vs, Node& Vd){
    queue<Node> Q;
    Node Vn, Vw;
    int i;
     
    //初始状态将起点放进队列Q
    Q.push(Vs);
    hash(Vw) = true;//设置节点已经访问过了!
     
    while (!Q.empty()){//队列不为空,继续搜索!
    //取出队列的头Vn
    Vn = Q.front();
     
    //从队列中移除
    Q.pop();
     
    while(Vw = Vn通过某规则能够到达的节点){
    if (Vw == Vd){//找到终点了!
    //把路径记录,这里没给出解法
    return true;//返回
    }
     
    if (isValid(Vw) && !visit[Vw]){
    //Vw是一个合法的节点并且为白色节点
    Q.push(Vw);//加入队列Q
    hash(Vw) = true;//设置节点颜色
    }
    }
    }
    return false;//无解
    }
    • 总结(总)
    • DFS适合此类题目:给定初始状态跟目标状态,要求判断从初始状态到目标状态是否有解。
    • BFS适合此类题目:给定初始状态跟目标状态,要求从初始状态到目标状态的最短路径。
    • 参考资料
  • 相关阅读:
    MyEclipse数据库反向生成实体类
    Struts2部分标签
    如何使用 Jmeter 发送 Json 请求
    [转]Perfmon
    Jmeter 施压 SQL server数据库的时候,如何设置?
    Tomcat 安装之后,双击Tomcat.exe,无法运行成功,怎么办?
    Jmeter 在什么情况下定义多个thread group?
    Watir RAutomation VS AutoIt to deal with popup
    RAutomation 在 Watir中的使用
    AutoIt:如何处理应用程序端口被占用的情况
  • 原文地址:https://www.cnblogs.com/zhongzihao/p/7436660.html
Copyright © 2020-2023  润新知