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

news2025/2/11 15:41:27

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。

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

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

相关文章

Kotlin协程详解——协程上下文

目录 一、上下文结构 get()获取元素 minusKey()删除元素 fold()元素遍历 plus()添加元素 CombinedContext Key 二、协程名称CoroutineName 三、上下文组合 四、协程作用域CoroutineScope 五、典型用例 协程的上下文&#xff0c;它包含用户定义的一些数据集合&#x…

手写一个C++ Android Binder服务及源码分析

手写一个C Android Binder服务及源码分析 前言一、 基于C语言编写Android Binder跨进程通信Demo总结及改进二、C语言编写自己的Binder服务Demo1. binder服务demo功能介绍2. binder服务demo代码结构图3. binder服务demo代码实现3.1 IHelloService.h代码实现3.2 BnHelloService.c…

Deep Dive into LLMs like ChatGPT - by Andrej Karpathy

https://www.youtube.com/watch?v7xTGNNLPyMIhttps://www.youtube.com/watch?v7xTGNNLPyMIDeep Dive into LLMs like ChatGPT - by Andrej Karpathy_哔哩哔哩_bilibilihttps://www.youtube.com/watch?v7xTGNNLPyMI转载自Andrej Karpathy Youtube ChannelThis is a general a…

react实例与总结(一)

目录 一、简单认识 1.1、特点 1.2、JSX语法规则 1.3、函数组件和类式组件 1.4、类组件三大属性state、props、refs 1.4.1、state 1.4.2、props 1.4.3、refs 1.5、事件处理 1.6、收集表单数据—非受控组件和受控组件 1.7、高阶函数—函数柯里化 1.8、生命周期—新旧…

51单片机(国信长天)矩阵键盘的基本操作

在CT107D单片机综合训练平台上&#xff0c;首先将J5处的跳帽接到1~2引脚&#xff0c;使按键S4~S19按键组成4X4的矩阵键盘。在扫描按键的过程中&#xff0c;发现有按键触发信号后(不做去抖动)&#xff0c;待按键松开后&#xff0c;在数码管的第一位显示相应的数字:从左至右&…

STM32 RTC亚秒

rtc时钟功能实现&#xff1a;rtc模块在stm32内部&#xff0c;由电池或者主电源供电。如下图&#xff0c;需注意实现时仅需设置一次初始化。 1、stm32cubemx 代码生成界面设置&#xff0c;仅需开启时钟源和激活日历功能。 2、生成的代码,需要对时钟进行初始化&#xff0c;仅需…

【Linux】深入理解linux权限

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;Linux 目录 前言 一、权限是什么 二、用户和身份角色 三、文件属性 1. 文件属性表示 2. 文件类型 3. 文件的权限属性 四、修改文件的权限属性和角色 1. …

json格式,curl命令,及轻量化处理工具

一. JSON格式 JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式。它基于一个子集的JavaScript编程语言&#xff0c;使用人类易于阅读的文本格式来存储和表示数据。尽管名字中有“JavaScript”&#xff0c;但JSON是语言无关的&#xff0c;几…

web直播弹幕抓取分析 signature

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01; 前言 最近遇到太多难点了卡了很久&am…

ABP框架9——自定义拦截器的实现与使用

一、AOP编程 AOP定义:面向切片编程&#xff0c;着重强调功能&#xff0c;将功能从业务逻辑分离出来。AOP使用场景&#xff1a;处理通用的、与业务逻辑无关的功能&#xff08;如日志记录、性能监控、事务管理等&#xff09;拦截器:拦截方法调用并添加额外的行为&#xff0c;比如…

CUDA 计算平台 CUDA 兼容性【笔记】

在 b 站看过的两个关于 CUDA 的技术分享&#xff0c;整理分享下对自己有用的课件。 20231130 2023第9期 聊一聊常见的AI计算平台库_哔哩哔哩_bilibili20230831 2023第6期 聊一聊CUDA兼容性_哔哩哔哩_bilibili 文章目录 CUDA 计算平台CUDA 函数库介绍英伟达三大护城河&#xff1…

最新消息 | 德思特荣获中国创新创业大赛暨广州科技创新创业大赛三等奖!

2024年12月30日&#xff0c;广州市科技局公开第十三届中国创新创业大赛&#xff08;广东广州赛区&#xff09;暨2024年广州科技创新创业大赛决赛成绩及拟获奖企业名单&#xff0c;德思特获得了智能与新能源汽车初创组【第六名】【三等奖】的好成绩&#xff01; 关于德思特&…

ubuntu安装VMware报错/dev/vmmon加载失败

ubuntu安装VMware报错/dev/vmmon加载失败&#xff0c;解决步骤如下&#xff1a; step1&#xff1a;为vmmon和vmnet组件生成密钥对 openssl req -new -x509 -newkey rsa:2048 -keyout VMW.priv -outform DER -out VMW.der -nodes -days 36500 -subj "/CNVMware/"ste…

python的列表、元组、深拷贝、浅拷贝(四)

python的列表 一、序列1. 序列定义2. 序列数据类型包括3.特点&#xff1a;都支持下面的特性 二、 列表1. 列表的创建2. 列表的基本特性(1) 连接操作符喝重复操作符(2) 成员操作符&#xff08;in , not in &#xff09;(3) 索引(4) 切片练习(5) for循环 3. 列表的常用方法(1) 一…

2.10作业

思维导图 C C语言

【深度学习】多目标融合算法(四):多门混合专家网络MMOE(Multi-gate Mixture-of-Experts)

目录 一、引言 二、MMoE&#xff08;Multi-gate Mixture-of-Experts&#xff0c;多门混合专家网络&#xff09; 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 2.3.1 业务场景与建模 2.3.2 模型代码实现 2.3.3 模型训练与推理测试 2.3.4 打印模型结构 三、总结 一、…

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决

RuoYi-Vue-Oracle的oracle driver驱动配置问题ojdbc8-12.2.0.1.jar的解决 1、报错情况 下载&#xff1a;https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle 用idea打开&#xff0c;启动&#xff1a; 日志有报错&#xff1a; 点右侧m图标&#xff0c;maven有以下报误 &…

C# OpenCV机器视觉:对位贴合

在热闹非凡的手机维修街上&#xff0c;阿强开了一家小小的手机贴膜店。每天看着顾客们自己贴膜贴得歪歪扭扭&#xff0c;不是膜的边缘贴不整齐&#xff0c;就是里面充满了气泡&#xff0c;阿强心里就想&#xff1a;“要是我能有个自动贴膜的神器&#xff0c;那该多好啊&#xf…

Baumer工业相机堡盟相机的相机传感器芯片清洁指南

Baumer工业相机堡盟相机的相机传感器芯片清洁指南 Baumer工业相机1.Baumer工业相机传感器芯片清洁工具和清洁剂2.Baumer工业相机传感器芯片清洁步骤2.1、准备步骤2.2、清洁过程1.定位清洁工具2.清洁传感器3&#xff0e;使用吹风装置 Baumer工业相机传感器芯片清洁的优势设计与结…

《我在技术交流群算命》(三):QML的Button为什么有个蓝框去不掉啊(QtQuick.Controls由Qt5升级到Qt6的异常)

有群友抛出类似以下代码和运行效果截图&#xff1a; import QtQuick import QtQuick.ControlsWindow {width: 640height: 480visible: truetitle: qsTr("Hello World")Button{anchors.centerIn: parentwidth: 100height: 40background: Rectangle {color: "red…