算法十——深度优先搜索和广度优先搜索

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。

搜索算法

算法是作用于数据结构之上的。深度优先搜索、广度优先搜索是作用于图这种数据结构之上的。图上的搜索算法可以理解为从一个顶点到另外一个顶点。

常用的搜索算法有:暴力的深度优先搜索、广度优先搜索,还有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。一层一层向外搜索。找到第三层。

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

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

相关文章

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol 52][第35篇]给针对ECDLP问题的Pollard rho,parallel Pollard rho攻击的一个粗略的描述

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 [1] http://www.cs.bris.ac.uk/~nigel/Crypto_Book/book.ps (pages 208 - 214) 转载连接&#xff1a;https…

spring学习(16):使用接口

目录结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

交易系统高并发下的幂等性设计原则

一、介绍 幂等性就是针对同一个请求&#xff0c;不管该请求被提交了多少次&#xff0c;该请求都将被视为同一个请求&#xff0c;服务端不应该将同一个请求进行多次处理&#xff0c;以确认处理逻辑的正确性&#xff0c;针对交易性系统幂等性的设计尤为重要&#xff0c;否则由于网…

工程中选择数据结构和算法的依据

1. 时间、空间复杂度不能和性能划等号 时间、空间复杂度不是时间执行和内存消耗的精确值。它们只是表示了随着数据量的增长&#xff0c;时间、空间的增长趋势。 代码的执行时间有时不跟时间复杂度成正比。我们常说算法是O(nlogn),O(n2n^2n2)这些都是基于大数据量&#xff08;…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第36篇]Index Calculus算法

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 我们这篇博客继续描述一种数学攻击&#xff0c;这种数学攻击被叫做Index Calculus(IC)算法。 注意这里Index…

DS博客作业07--查找

1.本周学习总结 1.思维导图 2.谈谈你对树结构的认识及学习体会。 查找是一种跟我们生活息息相关的算法&#xff0c;最典型的例子就是搜索引擎&#xff0c;而评价一种查找算法的优劣的关键就是查找速度&#xff0c;生活中我们往往要在大量数据查找自己所需要的东西&#xff0c;如…

easyUI学习笔记二

1&#xff0e; 拖拉大小 <!DOCTYPE html> <html> <head><title>easyui学习</title><script type"text/javascript" src jquery-easyui/jquery.min.js> </script><script type"text/javascript" src jquer…

C语言—每日选择题—Day62

隔一天更新解析 第一题 1. 在使用标准C库时&#xff0c;下面哪个选项使用只读模式打开文件&#xff1f; A&#xff1a;fopen("foo.txt", "r") B&#xff1a;fopen("foo.txt", "r") C&#xff1a;fopen("foo.txt", "w&…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第37篇]The Number Field Sieve

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 转载链接&#xff1a;https://www.cnblogs.com/zhuowangy2k/p/12245636.html

大二下学期软件工程概论总结

软件工程概论这门课可以算是我本学期最辛苦的一门课了。但与此同时这门课给我带来的收获和其他课程相比&#xff0c;也不是一个量级的。 这学期我通过课上的学习与作业项目的完成过程&#xff0c;了解到软件开发由项目的确定到项目的需求分析&#xff0c;再到概要&#xff0c;详…

70. Climbing Stairs

输入&#xff1a;台阶数量n 输出&#xff1a;有多少种走法 规则&#xff1a;每次可以上一个台阶或者两个台阶 分析&#xff1a;想明白一件事情。如果现在在第k个台阶&#xff0c;那下一步可以到达第k1个台阶&#xff0c;或者第k2个台阶。换句话说想要到达第k个台阶&#xff0c;…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第39篇]侧信道攻击和故障攻击有什么区别

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 侧信道攻击(Side-channel attacks, SCA)是一类攻击者尝试通过观察侧信道泄露来推测目标计算的信息。&#x…

面向对象:包装类、对象处理、类成员

包装类 Java是面向对象编程语言&#xff0c;但也包含了八种基本的数据类型&#xff0c;这八种基本的数据类型不支持面向对象的编程机制&#xff0c;基本的数据类型也不具备对象的特性&#xff1a;没有成员变量、方法被调用。所有类型的变量都继承Object类&#xff0c;都可以当成…

mysql-安装报错计算机中丢失MSVCR100.dll文件丢失

https://blog.csdn.net/weirdo_world/article/details/82393330

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]40一般来说SPA和DPA的区别是什么

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 电磁(Electronmagnetic, EM)功率分析攻击被划分成两种类型的攻击&#xff0c;简单功率分析(SPA)或者差分功率…

LDAP入门

LDAP入门 首先要先理解什么是LDAP&#xff0c;当时我看了很多解释&#xff0c;也是云里雾里&#xff0c;弄不清楚。在这里给大家稍微捋一捋。首先LDAP是一种通讯协议&#xff0c;LDAP支持TCP/IP。协议就是标准&#xff0c;并且是抽象的。在这套标准下&#xff0c;AD&#xff08…

关于Java中的HashMap

1 容量总是2次幂 /*** Returns a power of two size for the given target capacity.*/static final int tableSizeFor(int cap) {int n cap - 1;n | n >>> 1;n | n >>> 2;n | n >>> 4;n | n >>> 8;n | n >>> 16;return (n <…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]41所有的侧信道分析都是能量分析吗

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 侧信道攻击(SCA)利用在密码算法的物理实现上下文中获得的信息&#xff0c;而不是针对理论弱点的经典密码分析…

spring学习(22):分层架构

pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 …

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol52]42蒙哥马利乘法,哪里泄漏侧信道路吗?

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 看看你的C代码为蒙哥马利乘法&#xff0c;你能确定它可能在哪里泄漏侧信道路吗? 几个月前(回到3月份)&…