14.深度优先搜索:一条路走到黑,撞墙就回头

发布时间:2026/9/8 19:13:23

14.深度优先搜索:一条路走到黑,撞墙就回头
一、什么是深度优先搜索深度优先搜索Depth-First Search简称 DFS是一种经典的图和树的遍历算法它的核心思想是尽可能深地探索每一条路径直到走不通了再回溯换另一条路继续探索。简单来说深度优先搜索就像走迷宫从起点出发选择一个方向一直往前走遇到岔路口就随便选一条路继续深入走到死胡同就退回到上一个岔路口换另一条没走过的路重复这个过程直到找到终点或者所有路都试过了。二、深度优先搜索的核心步骤深度优先搜索的核心步骤可以分为以下几步边界检查判断当前位置是否越界、是否是墙、是否已经走过标记访问将当前位置标记为已访问防止绕圈判断终点如果当前位置是终点返回成功递归探索依次尝试四个方向上、下、左、右递归调用自己回溯如果所有方向都走不通取消当前位置的访问标记返回失败。三、深度优先搜索的代码实现1. Python 版本直观易懂# 方向数组右、下、左、上 dr [0, 1, 0, -1] dc [1, 0, -1, 0] # 迷宫地图0表示通路1表示墙 maze [ [0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 1, 1, 1, 0], [0, 1, 0, 0, 0, 0, 1, 0], [0, 1, 0, 1, 1, 0, 1, 0], [0, 1, 0, 1, 0, 0, 1, 0], [0, 1, 0, 1, 0, 1, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 1, 1, 1, 0] ] # 访问标记数组 visited [[False for _ in range(8)] for _ in range(8)] # 路径记录 path [] def dfs(row, col): # 1. 边界检查越界、撞墙、走过 if row 0 or row 8 or col 0 or col 8 or maze[row][col] 1 or visited[row][col]: return False # 2. 标记访问 visited[row][col] True path.append((row, col)) # 3. 判断终点右下角是终点 if row 7 and col 7: return True # 4. 递归探索四个方向 for i in range(4): nr row dr[i] nc col dc[i] if dfs(nr, nc): return True # 5. 回溯所有方向都走不通 path.pop() return False # 测试从左上角(0,0)出发 if dfs(0, 0): print(找到路径) for p in path: print(p, end - ) else: print(没有找到路径)2. C 语言版本更贴近底层#include stdio.h #include stdbool.h #define ROWS 8 #define COLS 8 // 方向数组右、下、左、上 int dr[4] {0, 1, 0, -1}; int dc[4] {1, 0, -1, 0}; // 迷宫地图0表示通路1表示墙 int maze[ROWS][COLS] { {0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 1, 1, 1, 1, 1, 0}, {0, 1, 0, 0, 0, 0, 1, 0}, {0, 1, 0, 1, 1, 0, 1, 0}, {0, 1, 0, 1, 0, 0, 1, 0}, {0, 1, 0, 1, 0, 1, 1, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 1, 1, 1, 0} }; // 访问标记数组 bool visited[ROWS][COLS] {false}; // 路径记录 int path[ROWS * COLS][2]; int pathLen 0; bool dfs(int row, int col) { // 1. 边界检查越界、撞墙、走过 if (row 0 || row ROWS || col 0 || col COLS || maze[row][col] 1 || visited[row][col]) { return false; } // 2. 标记访问 visited[row][col] true; path[pathLen][0] row; path[pathLen][1] col; pathLen; // 3. 判断终点右下角是终点 if (row ROWS - 1 col COLS - 1) { return true; } // 4. 递归探索四个方向 for (int i 0; i 4; i) { int nr row dr[i]; int nc col dc[i]; if (dfs(nr, nc)) { return true; } } // 5. 回溯所有方向都走不通 pathLen--; return false; } int main() { if (dfs(0, 0)) { printf(找到路径\n); for (int i 0; i pathLen; i) { printf((%d, %d), path[i][0], path[i][1]); if (i pathLen - 1) { printf( - ); } } printf(\n); } else { printf(没有找到路径\n); } return 0; }四、深度优先搜索的特点空间复杂度O (深度)因为使用递归调用栈栈的深度等于探索的最大深度时间复杂度O (节点数 边数)因为每个节点和边最多被访问一次路径不一定最短深度优先搜索会先探索一条路到底不一定是最短路径最短路径需要用广度优先搜索BFS。五、深度优先搜索的优化为了提高深度优先搜索的效率可以进行以下优化剪枝提前排除不可能到达终点的路径减少不必要的探索记忆化搜索记录已经探索过的状态避免重复探索迭代实现使用栈代替递归减少递归调用栈的深度避免栈溢出。六、深度优先搜索的实际应用场景深度优先搜索是一种非常基础且重要的算法常见场景包括图和树的遍历遍历图或树的所有节点迷宫问题寻找迷宫的出路排列组合问题生成所有可能的排列组合回溯算法解决八皇后、数独等问题拓扑排序对有向无环图进行拓扑排序连通分量找出图中的所有连通分量。七、深度优先搜索 vs 广度优先搜索深度优先搜索和广度优先搜索是两种最常用的图遍历算法它们的区别如下八、总结深度优先搜索是一种经典的图和树的遍历算法它的核心思想是尽可能深地探索每一条路径直到走不通了再回溯换另一条路继续探索。深度优先搜索的时间复杂度为 O (节点数 边数)空间复杂度为 O (深度)路径不一定最短适合解决排列组合、回溯、连通分量等问题。希望这篇文章能帮助你理解深度优先搜索的原理和实现

相关新闻

实体店主没时间做内容?托管式文案剪辑外包省时高效

实体店主没时间做内容?托管式文案剪辑外包省时高效

2026/9/8 19:03:23

绝大多数实体店老板的日常状态是忙碌且碎片化的,接待客户、管理门店、处理售后、安排员工,几乎没有完整时间研究短视频运营。但短视频又是当下实体店唯一免费、高效、持续的线上引流渠道,不做就会丢失同城流量,做又没时间、没技术…

Gomega 发布流程全解:从 CHANGELOG 自动生成到 GitHub Release,以 Kubernetes 仓库内置 Gomega v1.40.0 为例

Gomega 发布流程全解:从 CHANGELOG 自动生成到 GitHub Release,以 Kubernetes 仓库内置 Gomega v1.40.0 为例

2026/9/8 19:03:23

Gomega 发布流程全解:从 CHANGELOG 自动生成到 GitHub Release,以 Kubernetes 仓库内置 Gomega v1.40.0 为例 【免费下载链接】kubernetes Production-Grade Container Scheduling and Management 项目地址: https://gitcode.com/GitHub_Trending/kube…

STM32C542R开发(3)----配置串口打印

STM32C542R开发(3)----配置串口打印

2026/9/8 19:03:23

STM32C542R开发.3--配置串口打印概述视频教学样品申请源码下载硬件准备参考程序生成STM32CUBEMX2时钟树配置DEBUG配置串口配置生成项目导入STM32CubeIDE设置工程编码添加头文件printf 重定向串口打印测试演示概述 在传统 STM32 开发中,我们通常会通过 STM32CubeMX …

5分钟上手的桌面API客户端:yaak接口测试全场景覆盖

5分钟上手的桌面API客户端:yaak接口测试全场景覆盖

2026/9/8 19:53:25

5分钟上手的桌面API客户端:yaak接口测试全场景覆盖 【免费下载链接】yaak The most intuitive desktop API client. Organize and execute REST, GraphQL, WebSockets, Server Sent Events, and gRPC 🦬 项目地址: https://gitcode.com/GitHub_Trendin…

10分钟上手Pot-Desktop:免费开源的跨平台翻译与OCR完整指南

10分钟上手Pot-Desktop:免费开源的跨平台翻译与OCR完整指南

2026/9/8 19:53:25

10分钟上手Pot-Desktop:免费开源的跨平台翻译与OCR完整指南 【免费下载链接】pot-desktop 🌈一个跨平台的划词翻译和OCR软件 | A cross-platform software for text translation and recognition. 项目地址: https://gitcode.com/GitHub_Trending/po/p…

OpenHarmony上RN滚动冲突排查与解决:NestedScroll与手势机制实践

OpenHarmony上RN滚动冲突排查与解决:NestedScroll与手势机制实践

2026/9/8 19:53:25

去年年底把一个 React Native 的新版本跑上 OpenHarmony 真机时,第一个让我加班到凌晨的问题不是环境配置,也不是包体积,而是页面上那个看似人畜无害的 NestedScroll 滚动冲突。外层 ScrollView 里套一个 FlatList,手指往上滑&…

Phase {PHASE_NUMBER} Learnings: {PHASE_NAME}

Phase {PHASE_NUMBER} Learnings: {PHASE_NAME}

2026/9/8 19:53:25

Phase {PHASE_NUMBER} Learnings: {PHASE_NAME} 【免费下载链接】get-shit-done A light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TCHES. 项目地址: https://gitcode.com/GitHub_Trending/getshi/g…

CATLASS × AscendC 算子调测 API:两行代码看清 kernel 内部

CATLASS × AscendC 算子调测 API:两行代码看清 kernel 内部

2026/9/8 19:53:25

CATLASS AscendC 算子调测 API:两行代码看清 kernel 内部 【免费下载链接】pot-desktop 🌈一个跨平台的划词翻译和OCR软件 | A cross-platform software for text translation and recognition. 项目地址: https://gitcode.com/GitHub_Trending/po/po…

基于YOLOv5的车牌识别实战:从数据训练到部署全流程记录

基于YOLOv5的车牌识别实战:从数据训练到部署全流程记录

2026/9/8 19:43:25

简介:基于YOLOV5的目标检测车牌定位与识别项目源码,面向计算机视觉初学者及需落地车牌识别场景的开发者,解决自然场景下车辆车牌快速定位与精准识别问题。压缩包共68个文件,以19个py源码脚本、9个yaml模型配置、5个pt预训练权重、…

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

2026/9/7 20:21:46

本文首发于“生态学者”!从“湿地面积”到“土壤碳密度”:为什么需要重新认识潮汐湿地蓝碳变化?潮汐湿地位于陆地与海洋的交汇地带,包括红树林、盐沼和潮滩,是全球重要的蓝碳生态系统。其土壤能够长期储存大量有机碳&a…

adb抓包

adb抓包

2026/9/8 4:55:53

前言 本文介绍如何通过 tcpdump 在 Android 手机上抓取网络数据包,并在电脑端使用 Wireshark 进行分析。适用于需要排查 App 网络请求、分析接口调用或调试网络问题的开发与测试场景。1. 手机要有 root 权限2. 下载 tcpdump3. adb push C:\Users\zhangkuixun\Downlo…

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

2026/9/7 8:03:37

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战 在云原生基础设施中,容器镜像体积直接决定了服务的部署速度与弹性扩容敏捷度。对于传统的 Go / Java 微服务,镜像体积通常被严格控制在 50MB 到 200MB 以内,拉取镜像只…

芯片良率波动可视化:动画拆解工艺因果,重建客户信任

芯片良率波动可视化:动画拆解工艺因果,重建客户信任

2026/9/8 0:02:30

芯片这个行业有个不太被人摆到台面上、但几乎每天都在发生的场景:客户拿着一条良率曲线截图问你,这批货的良率怎么掉了三个点,是不是工艺出问题了,产生的不良会不会流到他们产线上去。你解释了半天,客户似懂非懂&#…

PyTorch DataLoader参数冲突:sampler与shuffle互斥的根源与正确写法

PyTorch DataLoader参数冲突:sampler与shuffle互斥的根源与正确写法

2026/9/8 0:02:30

ValueError: sampler option is mutually exclusive with shuffle,这个报错我在 PyTorch 的 DataLoader 上至少见过几十次了,而且很有意思的是,它经常不是新手专属——很多写了好几年模型的老手,在从单机改成自定义采样器&#xf…

中国车企再破谣言,GAC吉利零跑获欧盟安全五星

中国车企再破谣言,GAC吉利零跑获欧盟安全五星

2026/9/8 0:02:30

有人可能在网上开着皮卡拍视频,声称中国电动车不仅性能不如美国大排量车型,安全性也堪忧。然而事实恰恰相反,GAC、吉利和零跑最新推出的电动车型在极为严苛的欧盟新车安全评鉴(Euro NCAP)测试中全部斩获满分。就在特斯…

远程协作的工作台整理

远程协作的工作台整理

2026/9/8 4:23:39

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/8 3:19:39

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/8 4:00:23

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…