【蓝桥杯训练】DFS与BFS讲解
创始人
2025-05-28 07:32:52
0次

1. DFS(深度优先遍历)

理论介绍

DFS属于图算法的一种,是针对图和树的遍历算法。深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用堆或栈来辅助实现DFS算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,如果遇到死路就往回退,回退过程中如果遇到没探索过的支路,就进入该支路继续深入,每个节点只能访问一次。

博主个人理解

DFS(深度优先遍历),是图论中的一种遍历方式,我们可以认为DFS是一个执着的人,不到南墙不回头,他会一直走到头,然后回溯,空讲比较抽象,我们直接来看DFS的一个应用,排列数字,如这样一个例题

image-20230314213628492

那么他是怎样去遍历呢? 以n=3为例,从根节点开始,第一层有三种选择方式分别是1,2,3,那么对应第二层就有2,3 或者1,3或者1,2这几种选择,可以看下面这张图

image-20230314213905982

image-20230314214024000

他的遍历是将每一种可能走到头,然后回溯的,这也是DFS的标志,执着!

代码实现

import java.util.*;
public class Main{static int N = 10,n;static int[] path = new int[N];//记录路径static boolean st[] = new boolean[N];//记录数字是否已被使用public static void main(String[] args){Scanner scan = new Scanner(System.in);n = scan.nextInt();dfs(0);//从第0层开始遍历}public static void dfs(int u){if(u == n){//遍历至最后一层for(int i = 0;iSystem.out.print(path[i]+" ");//输出结果之一}System.out.println();return;//结束,并回溯}for(int i = 1;i<=n;i++){if(!st[i]){//当前数字未被使用过path[u]=i;//记录当前这一层的数字st[i]=true;//将这个数字表示已使用过,这样接下来就不会再被使用dfs(u+1);//遍历下一层st[i]=false;//恢复现场}}}
}

主要解题思路,从0层开始以dfs的方式去遍历,如果判断到了最后一层则回溯,在每一层判断时,先枚举数字是否被使用过,如果未被使用过,则将其记为本层使用的数字,并标记使用过了,同时遍历下一层,注意要恢复现场,否则会对其余遍历造成影响。

2.BFS(宽度优先遍历)

理论介绍

广度优先搜索(也称宽度优先搜索)是连通图的一种遍历算法,也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和广度优先搜索类似的思想。属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。基本过程,BFS是从根节点开始,沿着树(图)的宽度遍历树(图)的节点。如果所有节点均被访问,则算法中止。一般用队列数据结构来辅助实现BFS算法。
博主个人理解

BFS是比较贪心且懒惰的一个人,他会优先去搜索自己周围最近的所有单位,直到最近的都被找过了,去找下一接近的,直至最后,也因为他的懒惰,所以这种算法使用于最短路径问题!还是直接来例题 走迷宫
在这里插入图片描述

读题可知,要求的是所有出路中最短的那一条,这正是BFS的适用解,我们看一下遍历过程

image-20230314215353061

要注意的是 每次拓展的是,能在规定步数内走到的所有点位!

代码实现

import java.io.*;
public class Main{static int N = 110;static int hh,tt,n,m;static int[][] g = new int[N][N];//用来存储迷宫地图static int[][] d = new int[N][N];//用来存储走的距离static PII[] q = new PII[N*N];//用来放每个点的下标public static int bfs(){hh = 0;tt = -1;d[0][0] = 0;//左上角,因为是起点,初始化为0q[++tt] = new PII(0,0);int[] dx = {-1,0,1,0};//上(-1,0) 下(1,0)int[] dy = {0,1,0,-1};//左(0,-1) 右(0,1),这里是图论中常用的坐标移动方法while(hh<=tt){//队列不空,说明还没有遍历过所有点PII t = q[hh++];//取出队头for(int i = 0;i < 4;i++){int x = t.first+dx[i];int y = t.second+dy[i];//这里是遍历四个方位if(x>=0 && x=0 && y//解释下条件     x移动后没有越界    y移动后没有越界  当前点位还没来过  这个点是通的,-1表示此路不通d[x][y]=d[t.first][t.second]+1;q[++tt] = new PII(x,y);//移动后的点符合最近且为遍历过,且不越界的条件,入队!}}}return d[n-1][m-1];}public static void main(String[] args)throws IOException{BufferedReader re = new BufferedReader(new InputStreamReader(System.in));//快读BufferedWriter wt = new BufferedWriter(new OutputStreamWriter(System.out));//快写String[] s = re.readLine().split(" ");n = Integer.parseInt(s[0]);m = Integer.parseInt(s[1]);for(int i = 0 ; i < n ;  i ++ ){String[] st = re.readLine().split(" ");for(int j = 0 ; j < m ;j ++ ){g[i][j] = Integer.parseInt(st[j]);//读入迷宫地图d[i][j] = -1;//将所有距离设为-1}}System.out.println(bfs());wt.close();}
}
class PII{//存储结构,就是存的坐标,因为要存在队列里,所以不能直接写,要包装以下int first,second;public PII(int first,int second){this.first  = first;this.second = second;}
}

主要解题思路,以bfs的方式遍历整个地图,用d数组来记录走了多远,那么d[n][m]就是最短距离,先遍历起点,然后按照其可以移动的位置,将所有可能存入队列中,遍历队列里的每一个点,并继续添加,直至所有点都被遍历完成,这样得出最后的答案。

相关内容

热门资讯

两只大牛股,紧急发声:不属实!... 5天3板超声电子:“超声电子高频板通过英伟达认证”情况不属实,目前无产品供货给英伟达9月13日晚间,...
科创板创新药企BD授权交易总额... 2026年半年度财报季已收官,在创新药企业以业绩扭亏和BD兑现吸引市场目光的同时,以CXO为代表的上...
蔚来李斌1-8月交付增近58%... 9月9日消息,上海蔚来汽车有限公司副总裁品牌与传播资深专家马麟在微博透露,9月8日下午,蔚来创始人、...
京东物流部署过万前置仓应对手机... IT之家 9 月 13 日消息,据京东物流黑板报,9 月,多个品牌旗舰手机集中上新。针对消费者希望尽...
特朗普让泽连斯基勿袭击俄柴油燃... 9月13日,当地时间9月13日,美国总统特朗普要求乌克兰总统泽连斯基停止袭击俄罗斯柴油燃料设施,称相...
下周,年内最便宜新股启动打新 ... 2026.09.13本文字数:1467,阅读时长大约2分钟作者 |第一财经 安卓封图 |AI生成下周...
北京:激活地理信息要素赋能城市... 9月13日,从北京市规划和自然资源委员会获悉,《北京市测绘地理信息条例》已由北京市第十六届人民代表大...
接下来该如何逃顶?建议看看这篇... 最近这段时间,很多朋友的心里其实都是悬着的。行情走到这个位置,大家见面聊得最多的就是,接下来到底该怎...
武汉:到2035年武汉区域科技... 9月13日,武汉市委十四届十三次全会召开,审议通过了《关于打造具有全球竞争力的开放创新生态 高水平建...
卡塔尔股市收盘上涨0.25% 9月13日,卡塔尔证券交易所主要股指今日收盘上涨0.25%,报9848.95点,上涨24.46点。全...