解析与实现二叉树
在数据结构与算法的学习中,二叉树无疑是一个重要且实用的数据结构。它不仅在理论上具有深刻的研究价值,更在实际应用中广泛存在,如搜索引擎的索引结构、文件系统的目录树、数据库的索引、游戏开发中的场景管理等等。本文将深入探讨二叉树的基本概念,并以JavaScript为编程语言,实现几种基本的二叉树操作,包括创建二叉树、遍历二叉树(前序、中序、后序)、搜索元素、添加元素和删除元素。
二叉树的基本概念
二叉树是一种特殊的树形数据结构,其中每个节点最多有两个子节点,通常被称为左子节点和右子节点。一个二叉树可以是空集(空树),也可以由一个根节点以及左右两个不相交的二叉树组成。
节点定义
在JavaScript中,我们可以定义一个二叉树的节点如下:
class TreeNode {constructor(value = 0, left = null, right = null) {this.value = value; // 节点的值 this.left = left; // 左子节点 this.right = right; // 右子节点 }
}
添加元素
在二叉搜索树(BST)中,添加元素需要保持树的排序性质。
function insert(root, value) {if (!root) return new TreeNode(value); // 如果树为空,则创建新节点 if (value < root.value) {root.left = insert(root.left, value); // 插入到左子树 } else {root.right = insert(root.right, value); // 插入到右子树 }return root;
}
删除元素
删除二叉树中的元素是一个相对复杂的操作,因为它需要处理多种情况。
function deleteNode(root, value) {if (!root) return null; // 如果树为空,则直接返回null if (value < root.value) {root.left = deleteNode(root.left, value); // 在左子树中删除 } else if (value > root.value) {root.right = deleteNode(root.right, value); // 在右子树中删除 } else {// 节点有两个子节点 if (root.left && root.right) {// 使用右子树的最小值节点(或左子树的最大值节点)来替换 let successor = findMin(root.right);root.value = successor.value;root.right = deleteNode(root.right, successor.value);}// 节点是叶子节点或只有一个子节点 else {root = root.left ? root.left: root.right;}}return root;
}// 辅助函数:找到给定节点的右子树中的最小值节点
function findMin(node) {let current = node;while (current && current.left) {current = current.left;}return current;
}
二叉树的遍历
遍历是二叉树操作中非常重要的一环,它允许我们按照特定的顺序访问树中的每个节点。常见的遍历方式有三种:前序遍历、中序遍历和后序遍历。
前序遍历
前序遍历首先访问根节点,然后遍历左子树,最后遍历右子树。
function preorderTraversal(root) {let result = [];function traverse(node) {if (node) {result.push(node.value); // 访问根节点 traverse(node.left); // 遍历左子树 traverse(node.right); // 遍历右子树 }}traverse(root);return result;
}
中序遍历
中序遍历首先遍历左子树,然后访问根节点,最后遍历右子树。
function inorderTraversal(root) {let result = [];function traverse(node) {if (node) {traverse(node.left); // 遍历左子树 result.push(node.value); // 访问根节点 traverse(node.right); // 遍历右子树 }}traverse(root);return result;
}
后序遍历
后序遍历首先遍历左子树,然后遍历右子树,最后访问根节点。
function postorderTraversal(root) {let result = [];function traverse(node) {if (node) {traverse(node.left); // 遍历左子树 traverse(node.right); // 遍历右子树 result.push(node.value); // 访问根节点 }}traverse(root);return result;
}
搜索元素
在二叉树中搜索元素,通常使用递归的方式进行。
function search(root, value) {if (!root) return false; // 如果树为空,则未找到 if (root.value === value) return true; // 如果找到值,则返回true // 否则在左子树或右子树中递归搜索 return search(root.left, value) || search(root.right, value);
}
总结
通过本文,我们详细探讨了二叉树的基本概念、遍历方法、搜索、添加和删除元素等基本操作。这些操作是理解和使用二叉树的基础,也是数据结构与算法学习中不可或缺的一部分。希望这些内容能够帮助你更好地掌握二叉树的相关知识,并在实际应用中灵活运用。
相关文章:
解析与实现二叉树
在数据结构与算法的学习中,二叉树无疑是一个重要且实用的数据结构。它不仅在理论上具有深刻的研究价值,更在实际应用中广泛存在,如搜索引擎的索引结构、文件系统的目录树、数据库的索引、游戏开发中的场景管理等等。本文将深入探讨二叉树的基…...
Java面向对象——内部类(成员内部类、静态内部类、局部内部类、匿名内部类,完整详解附有代码+案例)
文章目录 内部类17.1概述17.2成员内部类17.2.1 获取成员内部类对象17.2.2 成员内部类内存图 17.3静态内部类17.4局部内部类17.5匿名内部类17.5.1概述 内部类 17.1概述 写在一个类里面的类叫内部类,即 在一个类的里面再定义一个类。 如,A类的里面的定义B类&#x…...
操作系统笔记三
进程 把一个静态程序通过OS在内存中让cpu执行起来的动态执行过程叫进程 写代码都是用户态,而进程在执行过程中需要完成特定的功能,这些功能呢只有操作系统能提供,比如说读写文件,读写文件的过程是与硬盘打交道,这个过程…...
uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点
uniapp快速入门教程,内容来源于官方文档,仅仅记录快速入门需要了解到的知识点 目录 介绍uniapp 介绍uniapp x 介绍功能框架图创建项目&发布组件/标签的变化js的变化css的变化工程结构和页面管理 pages.jsonmanifest.json 应用配置组件easycom组件规…...
基于微信小程序的商品展示+ssm(lw+演示+源码+运行)
商品展示系统 摘 要 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,微信小程序被用户普遍使用,为方…...
【Linux】常用指令(下)(内含more、less、 head、tail、date、find、grep、zip、tar以及学习笔记)
文章目录 前言1. more指令2. less指令(重要)3. head指令4. tail指令5. 管道(做到学会使用即可)6. date指令6.1 时间戳 7. cal指令8. find指令9. grep指令10. zip/unzip指令11. tar指令 前言 Linux下的常用指令终于要在本文落下帷…...
DesignMode__unity__抽象工厂模式在unity中的应用、用单例模式进行资源加载
目录 抽象工厂模式 思维导图 接口(抽象类) 工厂接口 抽象产品类 抽象武器接口 抽象人物接口 具体工厂和具体产品 具体工厂 (1)产品接口,生成具体人物 (2)武器接口,生成具体…...
Leetcode3289. 数字小镇中的捣蛋鬼
Every day a Leetcode 题目来源:3289. 数字小镇中的捣蛋鬼 解法1:哈希 代码: /** lc appleetcode.cn id3289 langcpp** [3289] 数字小镇中的捣蛋鬼*/// lc codestart class Solution { public:vector<int> getSneakyNumbers(vector…...
13_Python的高阶函数
高阶函数 高阶函数是Python编程中一个非常强大和有用的特性,它们允许程序员编写更简洁、更抽象的代码。 Python中的高阶函数是那些至少满足以下一个条件的函数: 接受一个或多个函数作为输入(也就是说,它的参数之一是函数&#…...
清空当前机器所有Docker容器和镜像
sudo docker stop $(sudo docker ps -aq) sudo docker rm $(sudo docker ps -aq) sudo docker rmi $(sudo docker images -q)删除当前机器上的所有Docker镜像是一个高风险操作,因为它会删除所有镜像,包括那些可能正在被容器使用的镜像。在执行此操作之前…...
FreeRTOS学习——Systick中断、SVC中断、PendSV中断
FreeRTOS学习——接口宏portmacro.h,仅用于记录自己阅读与学习源码 FreeRTOS Kernel V10.5.1 port :GCC/ARM_CM7 文章目录 Systick源码触发方式 SVC源码触发方式 PendSV源码触发方式 相关汇编指令 Systick 源码 在Systick中断xPortSysTickHandler中&am…...
汇量科技大数据面试题及参考答案
如何在 SQL 中处理三个字段完全一样的去重?在 Scala 中又该如何实现? 在 SQL 中,可以使用多种方法来处理三个字段完全一样的去重。一种常见的方法是使用 DISTINCT 关键字结合多个字段来实现。例如,假设有表 table_name,包含字段 field1、field2 和 field3,可以使用以下 S…...
移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——14.AVL树
1.AVL 树 1.1AVL 树的概念 二叉搜索树虽可以缩短查找的效率,但如果数据有序或接近有序二叉搜索树将退化为单支树,查 找元素相当于在顺序表中搜索元素,效率低下。因此,两位俄罗斯的数学家G.M.Adelson-Velskii 和E.M.Landis在1962…...
Python 的数据类型与操作
一、常用内置类型(Built - in Types) Python 拥有多种内置数据类型,这些类型满足了各种编程需求,从简单的数据存储到复杂的数据结构表示。 1. 数值类型(Numeric Types) 整数(int)&a…...
Python燃烧废气排放推断算法模型
🎯要点 宏观能耗场景模型参数化输入数据,分析可视化输出结果,使用场景时间序列数据模型及定量和定性指标使用线图和箱线图、饼图、散点图、堆积条形图、桑基图等可视化模型输出结果根据气体排放过程得出其时间序列关系,使用推断模…...
Qt中多语言的操作(以QtCreator为例)
1、首先,我们在代码中与文本相关的且需要支持多语言的地方,用tr来包含多语言key(多语言key是我们自己定义的),如下 //举例 QPushButton* btnnew QPushButton(this); btn->move(20,20); btn->resize(100,50); //…...
计算机毕业设计 社区医疗服务系统的设计与实现 Java实战项目 附源码+文档+视频讲解
博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…...
html+css学习
html 元素 html元素是HTML的根元素,一个文档只能有一个,其他所有元素都是其后代元素 html有一个属性为lang,其作用是: 帮助语言合成工具确定要使用的发音帮助翻译工具确定要使用的翻译规则 当属性lang“en”则表示告诉其浏览器…...
2.gitlab ce 细粒度的权限控制
需求: 在提交merge reqeust时,必须指定审核人,并且要选审核人清单里的 有个code owners应该可以做到(gitlab ce应该也可以用) 下面是参考的文档 细粒度的代码权限怎么做?极狐GitLab 代码所有者来帮忙 -…...
G - Merchant Takahashi / F - Useless for LIS
G - Merchant Takahashi 首先考虑暴力 DP。 设最后一步走到编号 ii 的城镇的方案的最大收益为 fifi,则每次集市相当于是 fTi←fj−C∣Ti−j∣Pi(1≤j≤n)。 这样每次可以通过枚举 j 来转移,这样总时间复杂度是 O(nm) 的&…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
华为OD机试-食堂供餐-二分法
import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
