算法十——深度优先搜索和广度优先搜索
文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。
搜索算法
算法是作用于数据结构之上的。深度优先搜索、广度优先搜索是作用于图这种数据结构之上的。图上的搜索算法可以理解为从一个顶点到另外一个顶点。
常用的搜索算法有:暴力的深度优先搜索、广度优先搜索,还有A*、IDA*等启发式搜索。
实际应用举例
在社交网络中有六度分隔理论,就是一个人最多通过六个人可以认识另外一个人。一个用户的一度好友就是他的好友,二度好友是他好友的好友,以此类推。给你一个关系图,你可以找到一个用户的三度好友吗?
广度优先搜索(BFS)
BFS:先找离起始顶点最近的点,然后是次近,依次向外搜索。
下面的代码是无向图的BFS代码。
/*** 无向图*/
public class UnDirectedGraph {private int v;//顶点个数private LinkedList<Integer> adj[];//邻接表public UnDirectedGraph(int v){this.v = v;this.adj = new LinkedList[v];for(int i=0;i<v;i++){this.adj[i] = new LinkedList<>();}}public void addEdge(int s,int t){this.adj[s].add(t);this.adj[t].add(s);}/*** 广度优先搜索从s节点到t节点:打印从s到t的节点路径* @param s* @param t*/public void bfs(int s, int t) {if(s==t){System.out.println(s);return;}Queue<Integer> queue = new LinkedList<>();queue.offer(s);boolean[] visited = new boolean[this.v];visited[s] = true;int[] pre = new int[v];Arrays.fill(pre,-1);while(!queue.isEmpty()){int size = queue.size();for(int i =0;i<size;i++){//每一层int w = queue.poll();for(int j =0;j<this.adj[w].size();j++){int q = this.adj[w].get(j);if(!visited[q]){pre[q] = w;if(q==t){printPath(pre,s,t);return;}visited[q]=true;queue.offer(q);}}}}}private void printPath(int[] pre,int s,int t) {if(s!=t && pre[t]!=-1){printPath(pre,s,pre[t]);}System.out.print(t+"\t");}
}
这里三个重要的临时变量queue、visited、pre。
queue:是一个队列,存储已经被访问,但是邻接点还没有被访问的节点。
visited:记录已经访问过的节点,防止重复访问。
pre:记录从哪个节点可以达到下标所表示的节点。pre[w]记录从哪个节点达到w节点 。
时间复杂度分析:BFS中每个节点都会被访问一次,入队一次,每条边都会被访问一次,时间复杂度O(V+E)。V表示顶点个数,E表示边的个数。
空间复杂度分析:临时变量queue、visited、pre的个数都不会超过顶点个数。所以上O(V)。
上面的代码可以抽象出BFS代码的框架。
深度优先搜索(DFS)
DFS:DFS是从起始顶点开始,按照一条路径一直走到终点t或者不能再走下去。然后返回到上一个可选择的状态,选择另外一条路径,继续走。DFS是一种非常有名的算法思想:回溯。
下图中实现代表搜索路径,虚线代表回退。
private boolean found = false;public void dfs(int s, int t) {boolean[] visited = new boolean[this.v];int[] pre = new int[v];Arrays.fill(pre,-1);dfs(s,t,visited,pre);printPath(pre,s,t);}private void dfs(int w, int t, boolean[] visited, int[] pre) {if(w==t){found = true;return;}visited[w] = true;if(!found){for(int j =0;j<this.adj[w].size() && !found;j++){int q = this.adj[w].get(j);if(!visited[q]) {pre[q] = w;visited[q]=true;dfs(q,t,visited,pre);}}}}
时间复杂度分析:从图中看每条边最多被访问2次,一次搜索,一次回退。时间复杂度O(E)。
空间复杂度分析:消耗内存主要是 visited、prev 数组和递归调用栈。visited、prev 数组和顶点个数相同。递归调用不会超过顶点的个数。所以空间复杂度O(V)。
适用范围
DFS和BFS搜索的空间复杂度都是O(V),当顶点个数很大的时候,就不适合这两种算法。
三度好友
上面提到的查找一个人的三度好友适合用BFS。一层一层向外搜索。找到第三层。
算法十——深度优先搜索和广度优先搜索相关推荐
- Java实现算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)
对算法导论中图的广度优先搜索(BFS)和深度优先搜索(DFS)用Java实现其中的伪代码算法,案例也采用算法导论中的图. import java.util.ArrayList; import java ...
- 数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)
目录 一.图的遍历概念 二.深度优先搜索(DFS) (一)DFS算法步骤 1.邻接表DFS算法步骤 2.邻接矩阵DFS算法步骤 (二)深度优先生成树.森林 (三)DFS的空间复杂度和时间复杂度 三.广 ...
- 八数码深度优先搜索_深度优先搜索和广度优先搜索
深度优先搜索和广度优先搜索 关于搜索&遍历 对于搜索来说,我们绝大多数情况下处理的都是叫 "所谓的暴力搜索" ,或者是说比较简单朴素的搜索,也就是说你在搜索的时候没有任何所 ...
- 深度优先搜索和广度优先搜索
深度优先搜索和广度优先搜索 在人工智能的运筹学的领域中求解与图相关的应用中,这两个算法被证明是非常有用的,而且,如需高效地研究图的基本性质,例如图的连通性以及图是否存在环,这些算法也是必不可少的. ...
- 学会二叉树不知道干啥?二叉树的深度优先搜索和广度优先搜索,我要打十个乃至二十个(打开你的LeetCode撸起来)学练并举
目录 一. 图解二叉树的深度优先搜索 二. 二叉树的广度优先搜索 (层序遍历) 三. 打开LeetCode 撸起来 至此, 咱多少被刚刚的后序非递归搞得可能有点小晕晕的, 没事,层序简单呀.... ...
- 深度优先遍历和广度优先遍历_图与深度优先搜索和广度优先搜索
什么是图? 图是一种复杂的非线性表结构.由若干给定的点一级任意两点间的连线所构成.图通常用来描述事物之间的特定关系, 代表的就是事物, 线就是事物之间所具有的关系.例如社交网络就是一种典型的图关系, ...
- 迷宫问题:深度优先搜索和广度优先搜索
迷宫问题:深度优先搜索和广度优先搜索 1.深度优先搜索可以使用栈实现,栈顶元素为当前节点 2.当前节点搜索下一节点,判断节点是否走得通,如果走得通任意方向走一步,走不通一直弹出栈内元素,直到走得通 3 ...
- 深度优先搜索与广度优先搜索区别和案例
今天周末,心血来潮打开LeetCode做一道题: https://leetcode-cn.com/problems/number-of-enclaves/ 看到题,我的第一想法是: 从边缘的陆地开始, ...
- 数据结构与算法(python):广度优先搜索(Breadth First Search,BFS)和深度优先算法(Depth First Search,DFS)
参考自 MOOC数据结构与算法Python版 目录 一.广度优先搜索 1.1 BFS算法过程 1.2 广度优先搜索算法分析 二.深度优先搜索 2.1 骑士周游 2.1.1 问题定义 2.1.2 构建骑 ...
最新文章
- .Net Core快速创建Windows服务
- from .pycaffe import Net, SGDSolver, NesterovSolver, AdaGradSolver, RMSPropSolver, AdaDeltaSolver,
- 血泪史:阿里云+ubuntu+vnc+xfce4
- KVO - 观察自定义属性值
- 【Android】选项卡使用
- cad加载dll_关于CAD三维建模的35个问题
- 6/6 音视频技术大咖在线直播,教你开发者硬核个人成长指南
- EEG有效连接工具包SIFT的介绍与安装
- ubuntu几款好用的代码编辑器
- php新浪微博 登录接口文档,php新浪微博登录接口用法实例,php新浪_PHP教程
- Win10麦克风显示这个设备正常但是没声音怎么解决
- WPF无边框窗体拖动
- vue如何整个页面添加loading
- 广电时评 | 中央主流媒体盛赞爱奇艺短剧新气象
- 2022茶艺师(中级)复训题库及模拟考试
- osg学习(三十一)osg、Qt的image
- TIDB简介及基础架构
- 套汇问题 Floyd
- Fiido Riding苹果app的技术支持网址
- 传统网络游戏(偏重MMORPG)的模块划分