首页 > 其他分享 >深度优先搜索DFS、广度优先搜索BFS

深度优先搜索DFS、广度优先搜索BFS

时间:2024-02-23 17:22:05浏览次数:29  
标签:优先 int DFS 访问 搜索 顶点 节点

深度优先搜索DFS

基本概念

深度优先搜索(Depth-First Search,DFS)是十分常见的图搜索方法之一。 深度优先搜索会沿着一条路径一直搜索下去,在无法搜索时,回退到刚刚访问过的节点。 它从初始节点出发,按预定的顺序扩展到下一个节点,然后从下一节点出发继续扩展新的节点,不断递归执行这个过程,直到某个节点不能再扩展下一个节点为止。 因此深搜有一句典型的句子来描述,就是:不撞南墙不回头! 以当前所在位置为起点,沿着一条路向前走,当碰到岔道口时,选择其中一个岔路前进。 如果选择的这个岔路前方是一条死路,就退回到这个岔道口,选择另一个岔路前进。如果岔路中存在新的岔道口,那么仍然按上面的方法枚举新岔道口的每一条岔路。这样,只要迷宫存在出口,那么这个方法一定能够找到它。   深度优先搜索是模拟的一种算法,属于搜索算法,相比于广度优先搜索的代码要短一点,但是它比广搜较难理解,毕竟人家的递归可不是吹的……深搜的想法是首先选取一个未访问的点作为源节点。从源节点选取一条路一直往下走,沿着当前顶点的边,访问这条路线,直到走不下去为止。这时返回上一顶点,继续试探访问此顶点的其余子顶点,直到当前顶点的子顶点都被访问过,那么,返回上一顶点,继续重复。从而实现遍历。  

应用场景

深搜也属于递归的一种算法,主要可以解决的问题是:有多少种方案(计算方案数)判断能否到达终点 但是它无法算出共有几步,如果要计算几步的话,需要用广搜(广度优先搜索)
void fun(int x,int y){
        int tx,ty;
        if(满足条件)
        输出/方案数加一;
        else
        for(int i=0;i<4;i++)   //遍历所有可行的待扩展点
        {
            tx=dx[i]+x,ty=dy[i]+y;    //切换点的坐标,以扩展点作为新的起点
            if(不越界,没走过,可以走)  //判断待扩展点是否可行
            {
                标记走过;      //标记已经走过
                fun(tx,ty);   //向下递归深搜
                回溯(可有可无)
            }
        }
}

算法思想

扩展访问顺序

深度优先遍历的秘籍:后访问的节点,其邻接点先被访问。 根据深度优先遍历的秘籍,后来的先服务,这可以借助“栈”来实现。递归本身就是使用“栈”实现的,因此使用递归的方法更方便。 深度优先遍历图的方法是,从图中某顶点v出发: 1、访问顶点v; 2、依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问; 3、若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。  

算法流程

step1、初始化图中的所有节点为均未被访问。 step2、从图中的某个节点v出发,访问v并标记其已被访问。 step3、依次检查v的所有邻接点w,如果w未被访问,则从w出发进行深度优先遍历 (递归调用,重复步骤(2)和(3),以扩展节点为新的起点) 访问到尽头时,回到上一个节点,按顺序检查下一条岔路 step3中有一个重点是对邻接点的访问顺序  

深度优先搜索示例程序

int path[A];
bool st[A];         //标记是否被搜过的数组
void dss(int u )
{
    if(u==n)   //如果遍历到底了就输出
    {
        for(int i = 0; i < n ; i++)
        cout<<path[i]<<" ";
        cout<<endl;
        return;//回到上一层
    }
    //当u<n时,说明还没填完。
    for(int i = 1 ; i<= n ;i ++)
    {
        if(!st[i])//如果这层i没有被用过。
        {
            path[u] = i;//u深度赋值为i
            st[i] = true;//标记i已近被用过。
            dss(u + 1);   //进入下一层
            st[i] = false;  
            //回溯时候要把i重新回到未标记的状态,不用恢复path[u] = 0是因为它会被覆盖
            //然后继续循环
            //循环完了后依然会回到上一层
        }
    }
}
 

广度优先搜索BFS

MC流水搜索 降谷羽WaterWay方法,属于广度优先搜索 方法一:广度优先搜索 思路及算法 我们从给定的起点开始,进行广度优先搜索。每次搜索到一个方格时,如果其与初始位置的方格颜色相同,就将该方格加入队列,并将该方格的颜色更新,以防止重复入队。WATER-WAY算法 注意:因为初始位置的颜色会被修改,所以我们需要保存初始位置的颜色,以便于之后的更新操作

示例程序

class Solution {
public:
    const int dx[4] = {1, 0, 0, -1};
    const int dy[4] = {0, 1, -1, 0};
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) 
        {
        int currColor = image[sr][sc];
        if (currColor == color) {
            return image;
        }
        int n = image.size(), m = image[0].size();
        queue<pair<int, int>> que; //open表,队列,用二元数对存坐标
        que.emplace(sr, sc);  //将坐标加入队列
        image[sr][sc] = color; //改色
        while (!que.empty())  //大循环:open队列不为空时
        {
            //需要复习STL队列数据结构
            //每次对队列中第一个坐标判断扩展
            int x = que.front().first, y = que.front().second;
            que.pop();
            for (int i = 0; i < 4; i++) //四方向入队列
            {
                int mx = x + dx[i], my = y + dy[i];
                if (mx >= 0 && mx < n && my >= 0 && my < m && image[mx][my] == currColor) 
                {
                    que.emplace(mx, my);
                    //可扩展,放入open队列
                    image[mx][my] = color;
                }
            }
        }
        return image;
    }
};

 

标签:优先,int,DFS,访问,搜索,顶点,节点
From: https://www.cnblogs.com/jk-2048/p/18030011

相关文章

  • day41 动态规划part3 代码随想录算法训练营 96. 不同的二叉搜索树
    题目:96.不同的二叉搜索树我的感悟:这题,考的概率不大,听一遍,过一遍就行。理解难点:二叉搜索树定义为什么是累加的听课笔记:代码示例:classSolution:defnumTrees(self,n:int)->int:dp=[0]*(n+1)#创建一个长度为n+1的数组,初始化为0d......
  • everything指定搜索路径
    1.在搜索选项里选择“匹配路径”,其他不要选,如下: 2.先指定路径。如只搜索F盘则输入F:\,后面再输入需要的内容,如找F盘里的冒泡: 3.例:只搜索E盘vscode文件夹,则先指定E:\vscode,再输入需要找的东  ......
  • 代码随想录算法训练营day02 | leetcode 977. 有序数组的平方、35.搜索插入位置、34.在
    题目链接:977.有序数组的平方-简单题目描述:给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。示例1:输入:nums=[-4,-1,0,3,10]输出:[0,1,9,16,100]解释:平方后,数组变为[16,1,0,9,100]排序后,数组变为[0,1,9,16,100]......
  • DFS算法模板(2488:A Knight's Journey)
    DFS算法(C++版本)题目一:链接:http://bailian.openjudge.cn/practice/2488/解析思路:骑士找路就是基本的DFS,用递归不断找到合适的路,找不到就回头直到找到合适的路。该题难点:要是实现字典序,也就是同样的两种选择,要走到A1而不是B1。所以就有了{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1......
  • 爬取搜狗指定词条对应的搜索结果页面(简易网页采集器)
    #UA检测:门户网站的服务器会检测对应请求的载体身份标识,如果检测到请求载体的身份标识为某一款浏览器,说明是正常用户通过浏览器发起的正常的请求#如果检测到非浏览器发起的请求,则表示请求可能为不正常的请求(爬虫),那么有可能就会拒绝该请求#UA:User-Agent:(请求身份载体的身份标识)i......
  • #根号分治,分块,dfs序#洛谷 7710 [Ynoi2077] stdmxeypz
    题目传送门分析首先把距离变成深度,用dfs序转成区间问题,考虑分块,散块直接改问题是整块,如果模数比较大,可以以深度为第一维下标差分标记,这样查询时就可以前缀和知道答案如果模数比较小,那么给该块打标记,查询时枚举模数即可,然后块长取1000,模数阈值取300,就能尽量减少时间代码#in......
  • # 代码随想录算法训练营day01 | leetcode 704. 二分查找、35.搜索插入位置、34.在排序
    题目链接:704.二分查找-简单题目描述:给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。示例1:输入:nums=[-1,0,3,5,9,12],target=9输出:4解释:9出现在nums中并且下标为4示......
  • 力扣 dfs之 437. 路径总和 III
    给定一个二叉树的根节点root ,和一个整数targetSum,求该二叉树里节点值之和等于targetSum的路径的数目。路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。 示例1:输入:root=[10,5,-3,3,2,null,11,3,-2,null,1],target......
  • Go语言精进之路读书笔记第31条——优先考虑并发设计
    31.1并发与并行1.并行方案在处理器核数充足的情况下启动多个单线程应用的实例2.并发方案重新做应用结构设计,即将应用分解成多个在基本执行单元(例如操作系统线程)中执行的、可能有一定关联关系的代码片段goroutine:由Go运行时负责调度的用户层轻量级线程,相比传统操作系统线程而......
  • selenium搜索标签,获取标签属性
    搜索标签1By.ID#根据id号查找标签bro.find_element(By.ID,'id内容')2By.NAME#根据name属性查找标签3By.TAG_NAME#根据标签名查找标签a_list=bro.find_elements(By.TAG_NAME,'a')4By.CLASS_NAME#按类名找dig=bro.find_element(By.CLASS_NAME,'diggit')......