深度优先搜索(Depth-First Search, DFS)

深度优先搜索(Depth-First Search, DFS)是一种用于遍历或搜索树形结构(如树、图等)的算法。它沿着树的深度方向尽可能深地搜索,只有当当前分支无法继续深入时才回退到前一个节点,并尝试其他未被访问的分支。DFS可以用于查找特定节点、判断图的连通性、生成树的遍历序列等任务。以下是DFS的主要特点和步骤:

主要特点

  1. 递归或栈实现:DFS可以采用递归或非递归(使用栈)的方式来实现。递归版本简洁明了,非递归版本通过手动模拟递归调用栈的行为,更适用于对递归深度有严格限制或者希望避免函数调用开销的场景。

  2. 搜索路径:DFS沿着一条路径深入搜索,直到到达叶子节点(在图中为无法继续前进的节点)或到达目标节点为止。在回溯过程中,它会“退回”到前一个节点,并尝试其他未被访问的子节点。

  3. 无环图的遍历:在无环图中,DFS能保证访问到每一个节点,并且对于无向图而言,有前序遍历、中序遍历和后序遍历三种方式,分别对应于访问节点、访问左子树和访问右子树的顺序不同。

  4. 连通性判断:DFS可以用于判断图的连通性。如果从一个起点出发,DFS能够访问到所有节点,则该图是连通的。对于有向图,还需要区分强连通和弱连通的概念。

  5. 记忆化搜索:DFS可以结合记忆化技术(即备忘录或动态规划的思想),避免重复搜索已经访问过且状态相同的子树,从而提高搜索效率,常用于解决最优化问题。

基本步骤

  1. 标记节点:通常需要一个数据结构(如数组或集合)来记录已访问的节点,防止在搜索过程中陷入无限循环。

  2. 选择起始节点:选择图中的一个节点作为起始节点,并将其标记为已访问。

  3. 递归/栈处理

    • 递归版本:对当前节点的每一个未访问的邻居节点,递归调用DFS函数。
    • 非递归版本:将当前节点的所有未访问邻居节点压入栈中,然后弹出栈顶节点进行处理,重复此过程直到栈为空。
  4. 回溯:当当前节点的所有邻居节点均已被访问(或当前节点无邻居),回溯到前一个节点,继续处理其未访问的邻居。

  5. 结束条件:当所有节点都被访问过,或者目标节点被找到(如果适用),DFS结束。

应用实例

DFS在许多问题中都有应用,如迷宫求解、拓扑排序、图的连通分量识别、遍历文件系统目录结构、社交网络中的好友推荐等。在编程竞赛、数据结构课程以及实际工程问题中,DFS是一种基础且重要的搜索算法。

以下是DFS的Python实现示例(以无向图为例,使用邻接表表示):

 

Python

1def dfs(graph, start, visited=None):
2    if visited is None:
3        visited = set()
4
5    visited.add(start)
6
7    for neighbor in graph[start]:
8        if neighbor not in visited:
9            dfs(graph, neighbor, visited)
10
11    return visited
12
13# 示例
14graph = {
15    'A': ['B', 'C'],
16    'B': ['A', 'D', 'E'],
17    'C': ['A', 'F'],
18    'D': ['B'],
19    'E': ['B', 'F'],
20    'F': ['C', 'E']
21}
22
23visited_nodes = dfs(graph, 'A')
24print("Visited nodes:", visited_nodes)

实现了DFS的基本逻辑,通过递归方式遍历图中从起始节点start出发的所有可达节点,并使用集合visited记录已访问节点,避免重复访问。遍历结束后,返回所有已访问节点的集合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/835488.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

活字格中读取粘贴板中的内容:剪切板cp,我手机就吃这一亲!

哟,小伙伴们,今天我们来聊聊一个有趣的小功能吧! 你们应该都熟悉"复制粘贴"这个操作了吧?用CtrlC和CtrlV就可以将文字或图片等内容从一处复制到另一处,方便极了。但是,如果你的设备没有键盘,就没法使用快捷键了,那可怎么办呢? 别急,我们有解决办法!开发应用的时候…

【复利思维 + 项目成功方程式】用1年,超越别人38年!

复利思维—每天进步1%。 一年后会比现在的自己优秀38倍。在做任何事情时都要考虑,这件事是否能随着时间不断积累扩大,不能积累价值的事情要及时调整和止损。 在这个过程中,千万不要陷入心理暗示的陷阱,尤其是越想得到的&#xf…

JVM调参实践总结

JVM调优–理论篇从理论层面介绍了如何对JVM调优。这里再写一篇WIKI,尝试记录下JVM参数使用的最佳实践,注意,这里重点介绍HotSpot VM的调参,其他JVM的调参可以类比,但不可照搬。 Java版本选择 基于Java开发应用时&…

政安晨:【Keras机器学习示例演绎】(四十二)—— 使用 KerasNLP 和 tf.distribute 进行数据并行训练

目录 简介 导入 基本批量大小和学习率 计算按比例分配的批量大小和学习率 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益,如有不足之处,欢迎在…

Excel日期数字转化成时间格式

1、5位数字转化成yyyy/mm/dd 要考虑闰年的小细节 // 输入数字转成日期(5位,excel表格日期),默认转换成YYYY-MM-DD export function numberToDate(number, format) {if (number ! undefined) {let date new Date((number - 1) *…

IDEA中的常见注解

下面是对每个注解的详细解释: Override:这个注解用于标记一个方法覆盖或实现了父类或接口中的方法。如果一个方法标记为Override,但实际上没有覆盖或实现父类或接口中的方法,编译器会报错。 Deprecated:这个注解用于标…

机器学习求数组的迹

机器学习求数组的迹、也叫求矩阵的迹。 矩阵的迹,也称为迹数,是矩阵主对角线上所有元素的和。矩阵的迹具有以下重要性质:- 不变性:矩阵的迹在转置、加法、乘法等运算下保持不变。- 特征值关系:一个方阵的迹等于其所有特…

微服务全局异常处理

1.使用两个注解RestControllerAdvice 和 Excetionhandler(valueExcetption.class) 2.第一个注解RestcontrollerAdvice用于注解类,RestControllerAdvice可以捕获整个应用程序中抛出的异常,并对它们进行处理。这样可以实现在整个应用程序范围内统一处理异…

高标准农田建设项目天空地一体化智慧监管平台

一、建设背景 党中央、国务院高度重视高标准农田建设。国务院办公厅印发的《关于切实加强高标准农田建设提升国家粮食安全保障能力的意见》 明确提出,大力推进高标准农田建设,到2022年,建成10亿亩高标准农田,以此稳定保障1万亿斤以…

《C语言文件处理:从新手到高手的跃迁》

📃博客主页: 小镇敲码人 💚代码仓库,欢迎访问 🚀 欢迎关注:👍点赞 👂🏽留言 😍收藏 🌏 任尔江湖满血骨,我自踏雪寻梅香。 万千浮云遮碧…

寻找最大价值的矿堆 - 矩阵

系列文章目录 文章目录 系列文章目录前言一、题目描述二、输入描述三、输出描述四、Java代码五、测试用例 前言 本人最近再练习算法,所以会发布一些解题思路,希望大家多指教 一、题目描述 给你一个由’0’(空地)、‘1’(银矿)、‘2’(金矿)组成的地图…

Spring Cloud Gateway 全局过滤器

系列文章目录 文章目录 系列文章目录前言 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。 全局过滤器作用于所…

TypeScript:JavaScript的超集

什么是TypeScript? TypeScript是一种由Microsoft开发的开源语言,它在JavaScript的基础上增加了类型系统和编译时的类型检查。TypeScript旨在解决JavaScript在大规模应用开发中遇到的问题,特别是在类型安全性方面。它可以编译成纯JavaScript代…

Visual Studio 安装教程 超级详细 (亲测有效)

1.1 VS2019安装 网址:Visual Studio: 面向软件开发人员和 Teams 的 IDE 和代码编辑器 下载完成之后双击.exe文件 步骤严格如下安装 默认语音包为中文(简体) 安装位置可以自行选择,完成以后就可以点击安装了。 安装完毕以后需要重…

深度探索Java工厂模式:创新与灵活性的结合

在软件设计中,有效地组织对象的创建过程是至关重要的。Java工厂模式是一种优秀的设计模式,它能够在对象创建的过程中提供更大的灵活性和可扩展性。本文将深入探讨工厂模式的不同实现方式,并提供详细的代码示例,以帮助读者更好地理…

docker cuda 宿主机访问docker 内部jupyter notebook

先运行一个容器,并且把宿主机端口映射到jupyter的8888 docker run -it --gpus all -p 9099:8888 --networkmy_network - ubuntu_zzc_0510 1.生成配置文件 jupyter notebook --generate-config 2.修改配置文件 vim ~/.jupyter/jupyter_notebook_config.py c.S…

java技术总结

1.java基本数据类型? byte 1,short 2 ,int 4,long 8 ,float 4,double 8,boolean 1,char 2 2.java为什么要有包装类型? 前 6 个类派生于公共的超类 Number,而 Character 和 Boolean 是 Object 的直接子类。 被 final 修饰, Java 内置的包装类是无法被继承的。 包装…

ubuntu postgresql 安装

在Ubuntu上安装PostgreSQL,你可以按照以下步骤进行: 使用apt包管理器安装 更新系统: 在安装任何软件之前,建议先更新你的操作系统。 sudo apt update sudo apt upgrade 安装PostgreSQL: 使用apt包管理器来安装Postg…

QT 小项目:登录注册账号和忘记密码(下一章实现远程登录)

一、环境搭建 参考上一章环境 二、项目工程目录 三、主要源程序如下: registeraccountwindow.cpp 窗口初始化: void registeraccountWindow::reginit() {//去掉?号this->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButt…

用标准的GNU/Linux命令替换Alpine上的精简版命令

Alpine Linux 是一个基于 musl libc 和 busybox 的轻量级Linux发行版,busybox 实现了很多常用类Unix命令的精简版,特点是体积很小,舍弃了很多不常用参数,我们简单对比一下标准Linux自带的 date 命令 和 Alpine下默认的 date 命令便…