从二叉树遍历深入理解BFS和DFS

1. 介绍

1.1 基础

BFS(Breadth-First Search,广度优先搜索)和 DFS(Depth-First Search,深度优先搜索)是两种常见的图和树的遍历算法。

BFS:从根节点(或起始节点)开始,逐层地对节点进行访问,先访问距离起始节点最近的所有节点,再依次访问距离更远的节点,像水波纹一样一层一层向外扩散。以下图为例:可以理解为BFS是横向遍历。在实现方案上一般使用队列来实现。
在这里插入图片描述
DFS:从根节点(或起始节点)开始,沿着一条路径尽可能深地访问节点,直到无法继续,然后回溯到上一个节点,再沿着另一条路径继续深入,直到访问完所有可达节点。以上图为例:可以理解为BFS是纵向遍历。在实现方案上一般使用递归或栈来实现。

1.2 复杂度分析

时间复杂度:对于图来说,BFS 和 DFS 的时间复杂度都是 (O(V + E)),其中 (V) 是顶点数,(E) 是边数。因为在遍历过程中,每个顶点和每条边都需要被访问一次。对于树结构,由于边数 (E = V - 1),时间复杂度为 (O(V))。

空间复杂度:BFS 的空间复杂度主要取决于队列的最大元素数量,最坏情况下为 (O(V))。DFS 的空间复杂度主要由递归调用栈的深度决定,最坏情况下为 (O(V))。

1.3 应用场景

BFS主要用于:

层次遍历:常用于树的层次遍历,可以按层依次访问树的节点。
最短路径问题:在无权图中,BFS 可以用来找到从起始节点到目标节点的最短路径。
社交网络中的好友推荐:可以通过 BFS 找到距离用户一定层次内的潜在好友。

DFS主要用于:

前中后序遍历:可用于树的遍历。
连通性检测:判断图中两个节点是否连通,或者找出图的所有连通分量。
拓扑排序:在有向无环图(DAG)中进行拓扑排序,用于确定任务的执行顺序。
求解迷宫问题:通过 DFS 尝试所有可能的路径,找到从起点到终点的路径。

2. 应用

2.1 BFS实现层次遍历

BFS伪代码如下:

1 创建一个队列Q,将起始节点s加入队列Q中。
2 当队列Q非空时,从队列Q中取出一个节点n。
3 如果节点n为目标节点,则找到了解,结束搜索。
4 否则,将节点n的未被访问过的邻居节点加入队列Q中。
5 重复步骤2~4,直到找到解或队列Q为空。

下边我们用BFS实现二叉树层次遍历:

public List<List<Integer>> levelShow(TreeNode root){
	List<List<Integer>> data = new ArrayList<>();
	// 空处理
	if(root == null){
		retrun data;
	}
	// 定义队列维护访问顺序
	Deuqe<TreeNode> queue = new LinkedListed<>();
	// 头节点入队
	queue.offer(root);
	while(!queue.isEmpty()){
		// 循环遍历完每一层级后再继续
		int size = queue.size();
		List<Integer> levelData = new ArrayList<>();
		for(int i = 0;i<size;i++){
			// 出队存储
			TreeNode node = queue.poll();
			// 防止空节点
			if(node == null){
				continue;
			}
			levelData.add(node.val);
			// 左节点入队
			if(root.left != null){
				queue.offer(root.left);
			}
			if(root.right != null){
				queue.offer(root.right);
			}
		}
		data.add(levelData);
	}
	retrun data;
} 

2.2 DFS实现前序遍历

DFS伪代码如下:

1 创建一个堆栈S,将起始节点s加入堆栈S中。
2 当堆栈S非空时,弹出堆栈S的栈顶元素top。
3 如果弹出元素是目标节点,则找到了解,结束搜索。
4 否则,将top的未被访问过的邻居节点加入堆栈S中。
5 重复步骤2~4,直到找到解或堆栈S为空。

下边我们用DFS实现二叉树前序遍历:

public List<Integer> frontShow(TreeNode root){
	List<Integer> data = new ArrayList<>();
	// 空处理
	if(root == null){
		retrun data;
	}
	// 定义栈维护访问顺序
	Stack<TreeNode> stack = new Stack<>();
	// 头节点入栈
	stack.push(root);
	while(!stack.isEmpty()){
		TreeNode node = stack.pop();
		// 防止空节点
		if(node == null){
			continue;
		}
		data.add(node.val);
		// 左节点入栈
		if(root.left != null){
			data.push(root.left);
		}
		if(root.right != null){
			data.push(root.right);
		}
	}
	retrun data;
} 

3. 总结

要理解BFS和DFS只需要熟记核心的一点:队列实现BFS,栈实现DFS。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【大数据安全分析】大数据安全分析技术框架与关键技术

在数字化时代&#xff0c;网络安全面临着前所未有的挑战。传统的网络安全防护模式呈现出烟囱式的特点&#xff0c;各个安全防护措施和数据相互孤立&#xff0c;形成了防护孤岛和数据孤岛&#xff0c;难以有效应对日益复杂多变的安全威胁。而大数据分析技术的出现&#xff0c;为…

亚博microros小车-原生ubuntu支持系列 27、手掌控制小车运动

背景知识 本节跟上一个测试类似&#xff1a;亚博microros小车-原生ubuntu支持系列&#xff1a;26手势控制小车基础运动-CSDN博客 都是基于MediaPipe hands做手掌、手指识别的。 为了方便理解&#xff0c;在贴一下手指关键点分布。手掌位置就是靠第9点来识别的。 2、程序说明…

MySQL第五次作业

根据图片内容完成作业 1.建表 &#xff08;1&#xff09;建立两个表:goods(商品表)、orders(订单表) mysql> create table goods( -> gid char(8) primary key, -> name varchar(10), -> price decimal(8,2), -> num int); mysql> create t…

Linux:软硬链接和动静态库

hello&#xff0c;各位小伙伴&#xff0c;本篇文章跟大家一起学习《Linux&#xff1a;软硬链接和动静态库》&#xff0c;感谢大家对我上一篇的支持&#xff0c;如有什么问题&#xff0c;还请多多指教 &#xff01; 如果本篇文章对你有帮助&#xff0c;还请各位点点赞&#xff0…

CSS 组合选择符详解与实战示例

在 Web 开发过程中&#xff0c;CSS 用于定义页面元素的样式&#xff0c;而选择器则帮助我们精确定位需要添加样式的元素。今天我们主要来讲解 CSS 中的组合选择符&#xff0c;它们能够根据 DOM 结构中元素之间的关系来选中目标元素&#xff0c;从而写出结构清晰、易于维护的 CS…

【Linux系统】—— 简易进度条的实现

【Linux系统】—— 简易进度条的实现 1 回车和换行2 缓冲区3 进度条的准备代码4 第一版进度条5 第二版进度条 1 回车和换行 先问大家一个问题&#xff1a;回车换行是什么&#xff0c;或者说回车和换行是同一个概念吗&#xff1f;   可能大家对回车换行有一定的误解&#xff0…

Winform开发框架(蝇量级) MiniFramework V2.1

C/S框架网与2022年发布的一款蝇量级开发框架&#xff0c;适用于开发Windows桌面软件、数据管理应用系统、软件工具等轻量级软件&#xff0c;如&#xff1a;PLC上位机软件、数据采集与分析软件、或企业管理软件&#xff0c;进销存等。适合个人开发者快速搭建软件项目。 适用开发…

win10 llamafactory模型微调相关②

微调 使用微调神器LLaMA-Factory轻松改变大语言模型的自我认知_llamafactory 自我认知-CSDN博客 【大模型微调】使用Llama Factory实现中文llama3微调_哔哩哔哩_bilibili 样本数据集 &#xff08;数据集管理脚本处需更改&#xff0c;见报错解决参考1&#xff09; 自我认知微…

AI大模型随机初始化权重并打印网络结构方法(以Deepseekv3为例,单机可跑)

背景 当前大模型的权重加载和调用&#xff0c;主要是通过在HuggingFace官网下载并使用transformer的库来加以实现&#xff1b;其中大模型的权重文件较大&#xff08;部分>100GB&#xff09;&#xff0c;若只是快速研究网络结构和数据流变化&#xff0c;则无需下载权重。本文…

前端项目打包完成后dist本地起node服务测试运行项目

1、新建文件夹 node-test 将打包dist 文件同步自定义本地服务文件夹node-test 中&#xff0c;安装依赖包。 npm install express serve-static cors 2、新创建服务文件js server.js 构建链接及端口 const express require(express); const path require(path); const co…

《语义捕捉全解析:从“我爱自然语言处理”到嵌入向量的全过程》

首先讲在前面&#xff0c;介绍一些背景 RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09; 是一种结合了信息检索与语言生成模型的技术&#xff0c;通过从外部知识库中检索相关信息&#xff0c;并将其作为提示输入给大型语言模型&#xff…

Word中Ctrl+V粘贴报错问题

Word中CtrlV粘贴时显示“文件未找到&#xff1a;MathPage.WLL”的问题 Word的功能栏中有MathType&#xff0c;但无法使用&#xff0c;显示灰色。 解决方法如下&#xff1a; 首先找到MathType安装目录下MathPage.wll文件以及MathType Commands 2016.dotm文件&#xff0c;分别复…

Git 与 Git常用命令

Git 是一个开源的分布式版本控制系统&#xff0c;广泛用于源代码管理。与传统的集中式版本控制系统不同&#xff0c;Git 允许每个开发者在本地拥有完整的代码库副本&#xff0c;支持离线工作和高效的分支管理。每次提交时&#xff0c;Git 会对当前项目的所有文件创建一个快照&a…

构建jdk17包含maven的基础镜像

1、先拉取jdk17基础镜像 docker pull openjdk:17-jdk-alpine 2、使用jdk17基础镜像创建容器 docker run -it openjdk:17-jdk-alpine sh 或 docker run -it --name jdk17 openjdk:17-jdk-alpine sh 3、修改镜像源地址 cat /etc/apk/repositories https://mirrors.aliyun.com…

【博客之星】GIS老矣尚能饭否?WebGIS项目实战经验与成果展示

目录 一、最前面的话 二、前言 1、关于“夜郎king” 3、GIS的“老骥伏枥” 4、WebGIS的“新程启航” 三、WebGIS技术简介 1、前、后技术简介 2、系统功能架构 四、WebGIS项目应用效果 1、应急灾害 2、交通运输 3、智慧文旅 4、其它项目 五、未来与展望 1、云计算…

如何在Vue中实现事件处理

在Vue中&#xff0c;事件处理是一个核心概念&#xff0c;它让我们能够响应用户的操作&#xff0c;比如点击按钮、输入文本等。Vue提供了一个简洁而强大的方式来绑定事件和处理事件。本文将介绍如何在Vue中实现事件处理&#xff0c;覆盖事件绑定、事件修饰符以及事件处理函数等内…

elementplus 使用日期时间选择器,设置可选范围为前后大于2年且只能选择历史时间不能大于当前时间点

需求&#xff1a;时间选择器可选的时间范围进行限制&#xff0c;-2年<a<2年且a<new Date().getTime()核心&#xff1a;这里需要注意plus版没有picker-options换成disabled-date属性了&#xff0c;使用了visible-change和calendar-change属性逻辑&#xff1a;另设一个参…

【MATLAB源码-第261期】基于matlab的帝企鹅优化算法(EPO)机器人栅格路径规划,输出做短路径图和适应度曲线

操作环境&#xff1a; MATLAB 2022a 1、算法描述 帝企鹅优化算法&#xff08;Emperor Penguin Optimizer&#xff0c;简称EPO&#xff09;是一种基于自然现象的优化算法&#xff0c;灵感来自于帝企鹅在南极极寒环境中的生活习性。帝企鹅是一种群居动物&#xff0c;生活在极端…

协议-ACLLite-ffmpeg

是什么&#xff1f; FFmpeg是一个开源的多媒体处理工具包&#xff0c;它集成了多种功能&#xff0c;包括音视频的录制、转换和流式传输处理。FFmpeg由一系列的库和工具组成&#xff0c;其中最核心的是libavcodec和libavformat库。 libavcodec是一个领先的音频/视频编解码器库&…

DuckDB:pg_duckdb集成DuckDB和PostgreSQL实现高效数据分析

pg_duckdb是PostgreSQL的扩展&#xff0c;它将DuckDB的列矢量化分析引擎和特性嵌入到PostgreSQL中。本文介绍pg_duckdb插件安装、特点以及如何快速入门使用。 pg_duckdb简介 pg_duckdb扩展将完全能够查询DuckDB中存储在云中的数据&#xff0c;就像它是本地的一样。DuckDB的“双…