当前位置: 首页 > news >正文

c++算法学习3——深度优先搜索

一、深度优先搜索的核心概念

DFS算法是一种通过递归或栈实现的"一条路走到底"的搜索策略,其核心思想是:

  1. 深度优先:从起点出发,选择一个方向探索到底,直到无路可走

  2. 回溯机制:遇到死路时返回最近的分叉点尝试其他路径

  3. 状态标记:记录已访问位置,避免重复访问

二、迷宫问题的DFS解法框架
1. 题目引入:

给定一个 n×n 的迷宫矩阵,判断是否存在从左上角 (0,0) 到右下角 (n-1,n-1) 的通路。移动规则如下:

  1. ​移动方向​​:每次只能向 ​​上、下、左、右​​ 四个方向移动一格
  2. ​通行规则​​:
    • . 表示可通行的路径
    • # 表示不可通行的墙壁
  3. ​特殊条件​​:
    • 若入口 (0,0) 或出口 (n-1,n-1) 为墙壁(#),直接判定为不可达
    • 路径不可走出迷宫边界
     ​​输入格式​
  •      ​​第1行​​:正整数 n (1 ≤ n ≤ 100),表示迷宫规模
  •     ​​后续n行​​:每行包含 n 个字符(. 或 #),用空格分隔,表示迷宫矩阵

    ​​示例输入​​:

   4

   . # . .

   . . # .

   # . . .

   . . . .

     ​​输出格式​:
  •  若存在路径,输出 YES
  •  否则输出 NO

​     示例输出​​:

  YES

2. 题目分析:

在走迷宫时,面临四个选择方向,我们可以按顺时针方向依次尝试。

首先观察右边,若可行则走向右边,并按相同方法继续探索;

接着查看下方,若可行则走向下方,再按相同方法探索;

然后查看左边,若可行则走向左边,继续按相同方式探索;

最后查看上方,若可行则走向上方,并继续以相同方式前进。

3.需要准备的工作
const int N = 110;  // 迷宫最大尺寸
char maze[N][N];    // 存储迷宫地图
bool visited[N][N]; // 标记访问状态
int n;              // 迷宫尺寸
// 方向数组:右→下→左→上(顺时针)
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
4. DFS核心模板
void dfs(int x, int y) {// 1. 边界判断:到达终点if (x == n-1 && y == n-1) {success = true;return;}// 2. 尝试四个方向for (int i = 0; i < 4; i++) {int nx = x + dx[i], ny = y + dy[i];// 3. 检查新位置有效性if (nx >=0 && nx <n && ny>=0 && ny<n && !visited[nx][ny] && maze[nx][ny]=='.') {visited[nx][ny] = true; // 标记已访问dfs(nx, ny);            // 递归探索// visited[nx][ny] = false; // 回溯时需要取消标记}}
}
三、无回溯DFS:判断路径存在性

问题要求:只判断能否从入口(0,0)走到出口(n-1,n-1)

关键实现:
// 初始化:标记障碍物
for (int i=0; i<n; i++) {for (int j=0; j<n; j++) {if (maze[i][j] == '#') visited[i][j] = true;}
}// 检查入口/出口有效性
if (maze[0][0]=='#' || maze[n-1][n-1]=='#') {cout << "NO";return 0;
}// 启动DFS
visited[0][0] = true;
dfs(0, 0);// 输出结果
cout << (success ? "YES" : "NO");
算法特点
  1. 不需要回溯:找到一条路径即可停止

  2. 不恢复访问标记:已探索区域无需重复访问

  3. 空间优化:使用visited数组避免循环


四、有回溯DFS:统计路径数量

问题变体:我们把最开始的问题改变一下,不求能否通过迷宫,而是计算从入口到出口的所有能通行的路径数量。

关键修改:
int pathCount = 0;  // 全局路径计数器void dfs(int x, int y) {if (x == n-1 && y == n-1) {pathCount++;  // 找到一条路径return;}for (int i=0; i<4; i++) {int nx = x + dx[i], ny = y + dy[i];if (nx>=0 && nx<n && ny>=0 && ny<n && !visited[nx][ny] && maze[nx][ny]=='.') {visited[nx][ny] = true;  // 标记占用dfs(nx, ny);visited[nx][ny] = false; // 关键回溯:释放位置}}
}
回溯机制图解
起点(0,0)
├─ 右→ (0,1) → ... → 终点 → 回溯
├─ 下→ (1,0) → ... → 终点 → 回溯
├─ 左→ 无效
└─ 上→ 无效

每次递归返回时取消标记,允许其他路径使用该位置

五、DFS执行过程分析

栈结构模拟(以3x3迷宫为例):

步骤 | 栈状态         | 当前动作
-----|---------------|-----------
1    | (0,0)         | 探索右侧(0,1)
2    | (0,0),(0,1)   | 探索下方(1,1)
3    | (0,0),(0,1)   | (1,1)是死路,回溯
4    | (0,0)         | 探索下方(1,0)
5    | (0,0),(1,0)   | 到达终点(2,2)

时间复杂度:O(4^n) 最坏情况(指数级)
空间复杂度:O(n²) 由递归深度决定

相关文章:

  • labelme安装及遇到的问题
  • C++STL-vector的使用
  • ocrapi服务docker镜像使用
  • 计算机网络安全问答数据集(1788条) ,AI智能体知识库收集! AI大模型训练数据!
  • [蓝桥杯]螺旋矩阵
  • 关于智能体API参考接口
  • GLM-4 模型
  • 【AI News | 20250605】每日AI进展
  • eNSP实现WDS手拉手业务
  • C# 中的 IRecipient
  • java.io.IOException: Broken pipe
  • Linux系统删除文件后的恢复方法
  • 用 NGINX 搭建高效 IMAP 代理`ngx_mail_imap_module`
  • 【深度学习-Day 23】框架实战:模型训练与评估核心环节详解 (MNIST实战)
  • nvidia系列教程-agx-orin安装ros
  • Vehicle HAL(5)--vhal 实现设置属性的流程
  • Three.js光与影代码分析及原理阐述
  • 能不能用string接收数据库的datetime类型字段
  • 晨读笔记 6-5 (主题:打造15分钟就业服务圈)
  • MySQL 索引:聚集索引与二级索引
  • 长沙网站优化分析/网络推广优化工具
  • 贵阳做网站公司/下载官方正版百度
  • 网站规划建设与管理维护的论文/网络宣传平台有哪些
  • phton可以做网站吗/查排名官网
  • 网站建设公司shundeit/河南网站建设哪个公司做得好
  • 南通企业网站怎么建设/查域名网站