Bootstrap

回溯算法和DFS联系

1、概述

回溯法是一种搜索法(穷举法),被称为通用的解题方法,本质是树的前中后序遍历,具体情况具体分析。这种方法适用于解一些组合数相当大的问题。通过剪枝(约束+限界)可以大幅减少解决问题的计算量(搜索量)。

深度优先搜索(DFS)是一种用于遍历或搜索树或图的算法,本质是树的前序遍历。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。


2、回溯和深度优先搜索的区别

回溯是一种更通用的算法。可以用于任何类型的结构,无论它是否是逻辑树(隐式树)还是显式树。

深度优先搜索是显式树或图结构相关的特定形式的回溯法。目的是遍历,不一定要通过回溯才能得到结果。

  • 回溯处理隐式树、显式树。可以是树的前中后序遍历
  • DFS 处理显式树,并且偏向于遍历穷举。大多数是树的先序遍历。

3、回溯法模版

 3.1 回溯法的基本思想

  1. 针对所给问题,定义问题的解空间;
  2. 确定易于搜索的解空间结构;
  3. 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。

3.2 代码模版

回溯算法模版

4、DFS模版(深度优先搜索)

  深度优先搜索基本模型

  void dfs(int step) {
        //判断边界
        //尝试每一种可能
        for (int i=1;i<=n;i++){
            //记录一些数据,例如
             sun++
            //继续下一步
            dfs(step+1);
        }
        //返回
    }

经典的DFS例题:啊哈算法的解救小哈和炸弹人(图的深度优先搜索)

//核心代码
    void dfs(int x, int y, int step) {
        int next[ 4][2]={
            {
                0, 1
            },//向右走
            {
                1, 0
            },//向下走
            {
                0, -1
            },//向左走
            {
                -1, 0
            }
        } ;//向上走
        int tx, ty, k;
        //判断是否到达小哈位置
        if (x == p && y == q) {
            if (step < min)
                min = step;
            return;
        }
        //枚举四种走法
        for (k = 0; k <= 3; k++) {
            //计算下一个点的坐标
            tx = x + next[k][0];
            ty = y + next[k][1];
            //判断是否越界
            if (tx < 1 || tx > n || ty < 1 || ty > m)
                continue;
            //判断该点是否有障碍物或者已经在路径上
            if (a[tx][ty] == 0 && book[tx][ty] == 0) {
                book[tx][ty] = 1;//标记这个点已经走过
                dfs(tx, ty, step + 1);//尝试下一个点
                book[tx][ty] = 0;//尝试结束,取消标记,恢复现场
            }
        }
        return;
    }

5、代码区别

子集树:x[t]=i;//记录痕迹,记录 t标记的每一层,试探每一层的所有可能

DFS图的遍历:dfs(tx, ty, step + 1);//从当前节点向下扩展,逐个试探

;