深度优先搜索(dfs)和广度优先搜索(bfs)

news2024/12/23 10:52:20

目录

一、前言

二、关于dfs和bfs有意思的小故事

三、深搜题例

1、小猫爬山链接

2、基本思路

3、代码

(1)python代码

四、广搜题例

1、武士风度的牛链接

2、基本思路

3、代码

(1)C++代码

(3)python代码


一、前言

对于学计算机的同学来说,学习算法是一件非常重要的事情,废话不多讲,我们来讲讲“dfs和bfs问题”。

二、关于dfs和bfs有意思的小故事

深搜,顾名思义,是深入其中、直取结果的一种搜索方法。
  

        如果深搜是一个人,那么他的性格一定倔得像头牛!他从一点出发去旅游,只朝着一个方向走,除非路断了,他绝不改变方向!除非四个方向全都不通或遇到终点,他绝不后退一步!因此,他的姐姐广搜总是嘲笑他,说他是个一根筋、不撞南墙不回头的家伙。
  深搜很讨厌他姐姐的嘲笑,但又不想跟自己的亲姐姐闹矛盾,于是他决定给姐姐讲述自己旅途中的经历,来改善姐姐对他的看法。他成功了,而且只讲了一次。从那以后他姐姐不仅再没有嘲笑过他,而且连看他的眼神都充满了赞赏。他以为是自己路上的各种英勇征服了姐姐,但他不知道,其实另有原因……
  深搜是这样跟姐姐讲的:关于旅行呢,我并不把目的地的风光放在第一位,而是更注重于沿路的风景,所以我不会去追求最短路,而是把所有能通向终点的路都走一遍。可是我并不知道往哪走能到达目的地,于是我只能每到一个地方,就向当地的人请教各个方向的道路情况。

        为了避免重复向别人问同一个方向,我就给自己规定:先问北,如果有路,那就往北走,到达下一个地方的时候就在执行此规定,如果往北不通,我就再问西,其次是南、东,要是这四个方向都不通或者抵达了终点,那我回到上一个地方,继续探索其他没去过的方向。

        我还要求自己要记住那些帮过他的人,但是那些给我帮倒忙的、让我白费力气的人,要忘记他们。有了这些规定之后,我就可以大胆的往前走了,既不用担心到不了不目的地,也不用担心重复走以前的路。哈哈哈……

深搜优缺点:

优点:
(1)能找出所有解决方案
(2)优先搜索一棵子树,然后是另一棵,所以和广搜对比,有着内存需要相对较少的优点

缺点:
(1)要多次遍历,搜索所有可能路径,标识做了之后还要取消。
(2)在深度很大的情况下效率不高

广搜,顾名思义,是多管齐下、广撒网的一种搜索方法。


  如果广搜是一个人,那么她一定很贪心,而且喜新厌旧!她从一点出发去旅游,先把与起点相邻的地方全部游览一遍,然后再把与她刚游览过的景点相邻的景点全都游览一边……一直这样,直至所有的景点都游览一遍。
  广搜属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。类似树的按层遍历,其过程为:首先访问初始点Vi,并将其标记为已访问过,接着访问Vi的所有未被访问过可到达的邻接点Vi1、Vi2…Vit,并均标记为已访问过,然后再按照Vi1、Vi2…Vit 的次序,访问每一个顶点的所有未被访问过的邻接点,并均标记为已访问过,依此类推,直到图中所有和初始点Vi有路径相通的顶点都被访问过为止。

广搜优缺点:

优点:
(1)对于解决最短或最少问题特别有效,而且寻找深度小
(2)每个结点只访问一遍,结点总是以最短路径被访问,所以第二次路径确定不会比第一次短

缺点
(1)内存耗费量大(需要开大量的数组单元用来存储状态)

注意:以上内容引用自(1条消息) 深搜和广搜的原理及优缺点_June·D的博客-CSDN博客_深搜和广搜

三、深搜题例

其实深搜和广搜的相关定义和性质知道上面的故事也差不多了(doge),主要还是多打打题吧。

1、小猫爬山链接

165. 小猫爬山 - AcWing题库

2、基本思路

见下图:

3、代码

(1)python代码

N,M=map(int,input().split())
ans=N
cat=[0 for _ in range(N+2)]
cap=[0 for _ in range(N+2)]

def dfs(now:int,cnt:int)->None:
    global ans,cat,cap
    if cnt>=ans:
        return
    if now==N+1:
        ans=min(ans,cnt)
        return
    
    # 尝试分配到已经租用的缆车上
    for i in range(1,cnt+1):  # 分配到已租用缆车
        if cap[i]+cat[now]<=M:
            cap[i]+=cat[now]
            dfs(now+1,cnt)
            cap[i]-=cat[now] # 还原
    # 新开一辆缆车
    cap[cnt+1]=cat[now]
    dfs(now+1,cnt+1)
    cap[cnt+1]-=cat[now]

for i in range(1,N+1):
    cat[i]=int(input())

# for i in range(0,N+1):
#     print(cat[i])

cat.sort(reverse=True)
cat=[0]+cat
dfs(1,0)

print(ans)

# for i in range(1,N+1):
#     print(cat[i])

C++代码见acwing题解区。

四、广搜题例

1、武士风度的牛链接

188. 武士风度的牛 - AcWing题库

2、基本思路

据说这一道题很经典,是一道广搜的”模板”题。只需用最原始的广搜,改一下方向即可.

3、代码

(1)C++代码

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>   //广搜需要用到队列是吧,所以我们给它加上一个头文件 

#define x first
#define y second

using namespace std;

typedef pair<int,int> PII;  //很经典的暴搜,首先这个题要搜索两维坐标,所以我们可以用pair存下标,这样的话代码能稍微短一些 

const int N=155;

int n,m;  // n行m列 
char g[N][N];  // 表示整一张地图 
int dist[N][N]; //表示到每一个格子的最短距离 

/*常用技巧  偏移量法  画图可知一个点的日字跳法到周围8个位置的偏移量*/
int dx[]={-2,-1,1,2,2,1,-1,-2};
int dy[]={1,2,2,1,-1,-2,-2, -1}; 

int bfs(PII start,PII end){
	queue<PII> q;
	memset(dist,-1,sizeof dist);
	dist[start.x][start.y]=0;
	q.push(start);
	
	while(q.size()){
		PII t=q.front();
		q.pop();
		
		for(int i=0;i<8;i++){
			int nx=t.x+dx[i],ny=t.y+dy[i];
			if(nx<0||nx>=n||ny<0||ny>=m||g[nx][ny]=='*'||dist[nx][ny]!=-1)
				continue; 
			dist[nx][ny]=dist[t.x][t.y]+1;
			
			if(make_pair(nx,ny)==end)
				return dist[nx][ny];
			q.push({nx,ny});
		}
	}
	return -1;
}

int main(){
	cin>>m>>n;
	for(int i=0;i<n;i++) cin>>g[i];
	
	PII start,end;
	for(int i=0;i<n;i++)
		for(int j=0;j<m;++j)
			if(g[i][j]=='K') start={i,j};
			else if(g[i][j]=='H') end={i,j};
			
	cout<<bfs(start,end)<<endl;
	return 0;
} 

(3)python代码

class pair:
    x,y=0,0
    def _init_(self)->None:
        self.x, self.y = 0, 0

def bfs(start:pair,end:pair)->int:
    global n,m,dist,g
    dx=[-2,-1,1,2,2,1,-1,-2]
    dy=[1,2,2,1,-1,-2,-2,-1]
    q=[]  # 用列表代替队列快多了
    dist[start.x][start.y]=0
    q.append(start)

    while len(q):
        t=q.pop(0)
##        print(t)
        for i in range(8):
            nx,ny=t.x+dx[i],t.y+dy[i]
            if nx<0 or nx>=n or ny<0 or ny>=m or g[nx][ny]=='*' or dist[nx][ny]!=-1:
                continue
            dist[nx][ny]=dist[t.x][t.y]+1
            if nx==end.x and ny==end.y:
                return dist[nx][ny]
            tmp=pair()
            tmp.x,tmp.y=nx,ny
            q.append(tmp)
    return -1

N=155
dist=[[-1]*N for _ in range(N)]
g=[]

m,n=map(int,input().split())

for i in range(n):
    g.append(input())

_start=pair()
_end=pair()

for i in range(n):
    for j in range(m):
        if g[i][j]=='K':
            _start.x=i
            _start.y=j
        elif g[i][j]=='H':
            _end.x=i
            _end.y=j

print(bfs(_start,_end))



'''
from queue import Queue

class pair:
    x,y=0,0
    def _init_(self)->None:
        self.x, self.y = 0, 0

def bfs(start:pair,end:pair)->int:
    global n,m,dist,g
    dx=[-2,-1,1,2,2,1,-1,-2]
    dy=[1,2,2,1,-1,-2,-2,-1]
    q=Queue() #显然这个是可以定义无限长度的
    dist[start.x][start.y]=0
    q.put(start)

    while q.qsize():
        t=q.get()
##        print(t)
        for i in range(8):
            nx,ny=t.x+dx[i],t.y+dy[i]
            if nx<0 or nx>=n or ny<0 or ny>=m or g[nx][ny]=='*' or dist[nx][ny]!=-1:
                continue
            dist[nx][ny]=dist[t.x][t.y]+1
            if nx==end.x and ny==end.y:
                return dist[nx][ny]
            tmp=pair()
            tmp.x,tmp.y=nx,ny
            q.put(tmp)
    return -1

N=155
dist=[[-1]*N for _ in range(N)]
g=[]

m,n=map(int,input().split())

for i in range(n):
    g.append(input())

_start=pair()
_end=pair()

for i in range(n):
    for j in range(m):
        if g[i][j]=='K':
            _start.x=i
            _start.y=j
        elif g[i][j]=='H':
            _end.x=i
            _end.y=j

print(bfs(_start,_end))
'''

以上,dfs和bfs

祝好

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

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

相关文章

现在的编程语言越来越多,为什么 C 和 C++ 还没有被现在的时代淘汰呢?

C/C会不会被时代淘汰&#xff1f;这个问题跳过了一步&#xff0c;关键是这个问题&#xff1a; C/C有哪些其它语言难以代替的特殊之处&#xff1f; 1、对实现细节的控制粒度 一般我们常说&#xff1a;C/C具有较高的执行效率。其实这句话不是特别准确&#xff0c;有时候它们并…

npm报错整理

npm报错整理一、代理1. 因为使用公司的镜像源导致的403 forbidden总结一、代理 1. 因为使用公司的镜像源导致的403 forbidden 在更新脚手架的时候&#xff0c;遇到了403的报错&#xff1a; 遇到问题不要怕&#xff0c;我们根据错误去解决就好。 &#xff08;1&#xff09;首…

【黄啊码】MySQL入门—13、悲观锁、乐观锁怎么用?什么是行锁、页锁和表锁?死锁了咋办?

大家好&#xff01;我是黄啊码&#xff0c;MySQL的入门篇已经讲到第12个课程了&#xff0c;今天我们继续讲讲大白篇系列——数据库锁 目录 从数据库管理的角度对锁进行划分 共享锁也叫读锁或 S 锁 排它锁也叫独占锁、写锁或 X 锁。 意向锁&#xff08;Intent Lock&#xf…

C++库——windows下使用Qt5.15.2+mingw64+msys2编译c++数学库GSL

文章目录准备配置msys2编译GSL准备 下载gsl库的源代码。大家可以到GSL的官网下载gsl的源代码。目前版本为2.7&#xff0c;下载完成后解压缩。 下载msys2。msys2是一套在windows上运行的用于构建库和程序的工具库&#xff0c;下载地址可以使用清华源的下载地址。下载完成后&…

【论文解读】伪装物体检测 Camouflaged Object Detection

文章目录伪装物体检测 Camouflaged Object DetectionSINet v1RF模块&#xff1a;PDC模块&#xff1a;SINet v2特征提取Texture Enhanced Module 纹理增强模块Neighbor Connection Decoder 邻居连接解码器Group-Reversal Attention 组反转注意力总结伪装物体检测 Camouflaged Ob…

计算机毕业设计之java+javaweb的烯烃厂压力管道管理平台

项目介绍 系统权限按管理员和用户这两类涉及用户划分。 (a) 管理员&#xff1b;管理员使用本系统涉到的功能主要有&#xff1a;主页、个人中心、通知公告管理、用户管理、管道信息管理、单位信息管理、管道统计信息管理等功能。 (b) 用户登录进入系统可以对主页、个人中心、通…

2022高频经典前端面试题(html+css+js上篇,含答案)

博主经历过多轮面试&#xff0c;因此想将自己的面试经验以及答题技巧&#xff0c;分享给即将面试找前端工作的同学。 2022高频经典前端面试题分为上中下三篇&#xff0c;分别会有html,css,js,es6,vue,ts,nodejs,以及hr面和反问面试官几个维度去进行&#xff0c;完整的还原面试场…

在 Linux 中使用 tcp 转储命令来分析网络

前言 Tcpdump是用于分析网络和查找相关网络问题的出色工具。它会在数据包经过时捕获数据包&#xff0c;并向您显示网络上正在发生的事情和传入情况。该命令的输出显示在 STDOUT 上&#xff0c;也可以存储在文件中。 感谢开发人员&#xff0c;他们将Tcpdump保留为开源项目。它…

LinkedIn最好工具-领英精灵有哪些批量加好友方法?

领英工具-领英精灵有哪些批量加好友方法 使用领英的人都会使用领英精灵&#xff0c;因为领英精灵是目前本土做得最好的领英工具&#xff0c;具有很多强大的功能。特别是拓展人脉方面&#xff0c;提供了很多批量加好友的方法。刚使用的新手可能不知道如何操作&#xff0c;下面就…

施耐德电气“创新开放日”走进中国软件研发中心 以软件与创新驱动产业“双转型”

来源 | 施耐德电气 2022年10月27日&#xff0c;施耐德电气在位于北京亦庄的中国软件研发中心举办“创新开放日”&#xff0c;充分展示其在中国深化研发的战略布局。当天&#xff0c;施耐德电气展示了该中心成立一周年以来的创新研发成果&#xff0c;并与合作伙伴共话软件发展趋…

【jsdoc-to-markdown】一步步实现js文件的文档生成

文章目录导读开发环境安装Vs code插件&#xff1a;Doxygen Documentation Generator效果优势jsdoc-to-markdown的使用了解 jsdocjsdoc-to-markdown安装创建测试文件example.jsjsdoc-to-markdown使用jsdoc-to-markdown踩坑&#xff01;&#xff01;&#xff01;参考资料导读 这个…

【C++】一文带你吃透string的模拟实现 (万字详解)

&#x1f308;欢迎来到C专栏~~ 模拟实现string (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort&#x1f393;&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句鸡汤&#x1f914;&#…

生态流量智能终端机 水电站生态流量多媒体智能终端-视频叠加、数据采集、远程传输

平升电子生态流量智能终端机 水电站生态流量多媒体智能终端是一款集人机交互、视频叠加、4G路由、数据采集、逻辑运算与远程传输功能于一体的多媒体智能终端设备。 此款产品为水电站生态流量监测项目的专用产品&#xff0c;便于监管单位及时掌握水电站的流量下泄情况&#xff…

【Django框架】——19 Django视图 01 路由配置

文章目录一、视图介绍二、路由配置1. 配置URLconf2.编辑项目中urls.py&#xff08;根路由&#xff09;3.创建应用中 urls.py (子路路由)4.路由文件urls.py5.API讲解一、视图介绍 视图就是应⽤用中views.py⽂文件中的函数 视图的第⼀个参数必须为HttpRequest对象&#xff0c;还…

计算多张图片的移位距离

( A, B )---25*30*2---( 1, 0 )( 0, 1 ) 做一个二分类的网络分类A和B&#xff0c;让A和B的训练集中都有多张图片&#xff0c;用一种平均值的办法把多张图片等效成两张图片&#xff0c;统计两张图片的移位距离&#xff0c;并比较移位距离和迭代次数的关系。 设AB训练集都只有两…

Python编程 赋值,逻辑,位运算符

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.赋值运算符 1.基本赋值运算符 2.注意 二.逻辑运算符 1.逻辑运算符使…

【LeetCode】No.70. Climbing Stairs -- Java Version

题目链接&#xff1a;https://leetcode.com/problems/climbing-stairs/ 1. 题目介绍&#xff08;Climbing Stairs&#xff09; You are climbing a staircase. It takes n steps to reach the top. 【Translate】&#xff1a; 你正在爬楼梯&#xff0c;爬到山顶要走n步。 Each…

最受欢迎的职业榜单!医生还是程序员?

最受欢迎的男友职业排行榜终于更新了&#xff0c;医生荣归榜首成为了第一名。 出人意外的是&#xff0c;公务员竟然只排名第六。 榜单上可以看出程序员也霸榜&#xff0c;占据了排行前三的位置。 程序员相对于医生有什么样的优势呢&#xff1f; 首先是逻辑分析能力。 虽然医生…

CMSC5707-高级人工智能之自编码器Auto-encoders

这章讲述模型框架和概念的时间较多&#xff0c;好像并没有涉及过多的运算&#xff0c;重在一些概念的理解。 Traditional Autoencoder 传统的自编码器常用来进行图像去噪的任务&#xff0c;需要了解其模型架构和流程。 自编码器由两部分组成&#xff1a;从Noisy Input到Z称为…

【附源码】计算机毕业设计java学生社团管理系统设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…