热门标签 | HotTags
当前位置:  开发笔记 > 后端 > 正文

bfs,dfs的通俗描述

bfs,dfs网上有很多关于它们的博文,学习的还是不要看我的,我只是看能不能用自己的话说出来。我也是小白。bfs中文名称是广度优先搜索,和dfs一样,两者都是搜索可以到达的所有

bfs ,dfs

网上有很多关于它们的博文,学习的还是不要看我的,我只是看能不能用自己的话说出来。我也是小白。

bfs 中文名称是广度优先搜索,和dfs 一样,两者都是搜索可以到达的所有状态。不同点是搜索顺序不同。dfs ,深度优先搜索,故名思议,会从一个状态出发,直到到达目标状态或者不满足某个条件而退回到上一个状态。很抽象是不是?没问题一开始我也看不懂,看完下面的例子再看,应该有点感觉了。
假如,你在一个迷宫寻找出口,来到了一个分岔口,选择其中一个,然后不断往前走,可能找到出口,可能又到达另一个分岔口,或者发现此路不通,此时你就要退回上一个分岔口,或者是起点。为了找到迷宫出口,我们需要把所有的状态记录下来,对当前的迷宫而言,这状态显然就是分岔口,是选择左呢,还是右呢,上还是下呢?都没关系,每一个都走走看。然后这有一个问题了,我们怎么知道这条路通不通呢?没办法,只能一直往下走才能知道通不通,通就最好,不通就退回上一个分岔口,选择另外一个方向。dfs 通常用递归实现。也可以用stack,stack的特点是 先进 后出,很符合dfs的特点,因为处于栈顶的元素(状态) ,就代表了我们目前所在的位置的上一个分岔口,如果此路不通,我们就把stack的元素pop()出来,选择另外一个方向,如果这分岔的所有方向都走过了,并且知道走不通,直接不再加入stack,选择此时的栈顶元素,即上上一个分岔口。当然,stack一开始是空的,因为你在起点还没遇到分岔口。当到达分岔口,把这分岔口入栈,然后选择一个方向往下走。用stack实现dfs比较麻烦,直接用递归最好了,递归本身就是用栈实现的。

如果给一个迷宫你叫你求到达出口的最短路径的长度,这时候我们若用dfs就显得繁琐了,因为我们需要走完整个迷宫,才能知道最短路径的长度。因为dfs是往深处搜索的,每次我们都要走完整条路才能确定这条路能不能到达出口,这对于求最短路径就不适合了。此时,bfs 上场了。它针对最短路径,最少操作非常合适。假设你现在依然在迷宫,并且会影分身,往前走,来到一个分岔口,它2个方向,你就分出一个分身,他走一个,你走一个,当然为了方便,我们假设你影分身很牛逼,分身不但可以分身,还能和分身交换位置。你和分身在不同方向同时往下走。不管先后顺序,你们都遇到了一个分岔口,重复上一步,影分身。继续,快变成篮球队的大家朝着不同方向继续前进了。运气非常好,分身们有一个到达了出口,此时你转移过去,恭喜了,顺利到达出口,并且此时你到达出口的分身走的路径是最短的,因为每一个分岔口都变出了分身,命令他们朝不同方向前进,意味着你从起点开始同时搜索所有可能的道路。可能你会吐槽我,分身一个走得慢,一个走得快,怎么办?很简单,让分身们和你同时走一步就可以了。这样,就能确保,到达出口的分身或者你是最短的路径。
每次前进一步,遇到分岔口,影分身,重复下去。回到这里,编程怎么实现了?怎么来管理这些影分身?可以想到,此时保存分岔口的选择就不太好了,很明显,根据上面的例子,我们要保存我们影分身的位置,每走一步跟新所有影分身的位置,而且每到达一个分岔口,我们影分身就会增加。这时要用队列来实现了。开始,队列只有一个,也就是你拉,拿出来,一直往前走,跟新此时的位置,去到分岔,变出几个影分身,并且加入队列,往前走,在一个一个拿出来,跟新他们的位置,加入队列尾,遇到分岔,就再次变出分身加入队列尾,一直重复下去,直到达出口。此时就break出来。
使用队列可以保证跟新完你和影分身当前位置,在开始跟新下一步。先进来的先处理。

到此吧,明天探讨一下题目。


推荐阅读
  • 面试题总结_2019年全网最热门的123个Java并发面试题总结
    面试题总结_2019年全网最热门的123个Java并发面试题总结 ... [详细]
  • 流处理中的计数挑战与解决方案
    本文探讨了在流处理中进行计数的各种技术和挑战,并基于作者在2016年圣何塞举行的Hadoop World大会上的演讲进行了深入分析。文章不仅介绍了传统批处理和Lambda架构的局限性,还详细探讨了流处理架构的优势及其在现代大数据应用中的重要作用。 ... [详细]
  • 本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ... [详细]
  • 本文探讨了使用 JavaScript 和 HTML5 Canvas 实现经典马里奥游戏克隆过程中遇到的碰撞检测和跳跃问题,并提供了详细的解决方案。 ... [详细]
  • RTThread线程间通信
    线程中通信在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取& ... [详细]
  • Vulnhub DC3 实战记录与分析
    本文记录了在 Vulnhub DC3 靶机上的渗透测试过程,包括漏洞利用、内核提权等关键步骤,并总结了实战经验和教训。 ... [详细]
  • 本文将详细介绍如何配置JDK 8u101的环境变量,包括下载、安装和环境变量的设置步骤。适用于64位和32位操作系统。 ... [详细]
  • 大华股份2013届校园招聘软件算法类试题D卷
    一、填空题(共17题,每题3分,总共51分)1.设有inta5,*b,**c,执行语句c&b,b&a后,**c的值为________答:5 ... [详细]
  • 本文详细介绍了如何对一个整数的二进制表示进行逆序操作。通过多种方法,包括直接法、查表法和分治法,帮助读者全面理解和掌握这一技术。 ... [详细]
  • Spring Boot + RabbitMQ 消息确认机制详解
    本文详细介绍如何在 Spring Boot 项目中使用 RabbitMQ 的消息确认机制,包括消息发送确认和消息接收确认,帮助开发者解决在实际操作中可能遇到的问题。 ... [详细]
  • 我自己做了一个网站图片的抓取,感觉速度有点慢抓取4000张图片可能得用15分钟左右的时间,我百度看用线程可以加快抓取,然后创建了5个线程抓取,但是5个线程是同步执行同样的操作一个图片就 ... [详细]
  • 在iOS开发中,多线程技术的应用非常广泛,能够高效地执行多个调度任务。本文将重点介绍GCD(Grand Central Dispatch)在多线程开发中的应用,包括其函数和队列的实现细节。 ... [详细]
  • RocketMQ 运维监控实践指南
    本文详细介绍了如何实现 RocketMQ 的运维监控,包括监控平台的搭建、常用运维命令及其具体用法。适合对 RocketMQ 监控感兴趣的读者参考。 ... [详细]
  • LeetCode 实战:寻找三数之和为零的组合
    给定一个包含 n 个整数的数组,判断该数组中是否存在三个元素 a、b、c,使得 a + b + c = 0。找出所有满足条件且不重复的三元组。 ... [详细]
  • 兆芯X86 CPU架构的演进与现状(国产CPU系列)
    本文详细介绍了兆芯X86 CPU架构的发展历程,从公司成立背景到关键技术授权,再到具体芯片架构的演进,全面解析了兆芯在国产CPU领域的贡献与挑战。 ... [详细]
author-avatar
狼与鹰的爱_340
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有