二叉搜索树:查找+插入+删除+性能分析

文章目录

    • 一、搜索树
      • 1.二叉搜索树的查找
      • 2.二叉搜索树的插入
      • 3.二叉搜索树的删除
      • 4.性能分析


一、搜索树

二叉搜素树 ( 二叉排序树 )

1.要么是空树

2.如果左子树不为空,则左子树上所有节点的值都小于根节点的值

3.如果右子树不为空,则右子树上所有节点的值都大于根节点的值

4.它的左右子树也是二叉搜索树

5.对二叉搜索树进行中序遍历,就能得到一个有序的数组

在这里插入图片描述

1.二叉搜索树的查找

  • 将要查找的值,和根节点比较

  • 比根节点小的在左树找,比根节点大的在右树找

最坏情况:按单分支树找,时间复杂度为树的高度 N

最好情况:完全二叉树、满二叉树,时间复杂度为树的高度:log2N,效率最高

为了解决单分支树的问题,采用AVL树解决。

  • AVL树:高度平衡的二叉搜索树,保证高度一直平衡(左右高度差不超过1),需要不断进行旋转(左旋、右旋、先左在右、先右再左),来保持平衡
  • 红黑树:加入了颜色,减少了旋转
public class BinarySearchTree {static class TreeNode {//静态内部类public int val;public TreeNode left;public TreeNode right;public TreeNode(int val) {this.val = val;}}public TreeNode root = null;/*** 查找二叉搜索树中指定的val值** @param val* @return*/public TreeNode find(int val) {TreeNode cur = root;while (cur != null) {if (cur.val == val) {return cur;} else if (cur.val < val) {cur = cur.left;} else {cur = cur.right;}}return null;}
  • 1.设cur结点为root位置
  • 2.cur的val如果小于目标val,cur移动到左子树
  • 3.cur 的val如果大于目标val,cur移动到右子树

2.二叉搜索树的插入

在这里插入图片描述

  • 1.如果是空树(root==null),直接插入根的位置
  • 2.如果不是空树,按照查找的逻辑找到要插入的位置,插入新结点
  • 3.都插入到了叶子结点,也就是cur为空时的位置
  • 4.所以要记录一个cur的双亲结点,来和val比较,决定cur==null时,插入的方向
/*** 插入一个数据** @param val*/public void insert(int val) {//root为空if (root == null) {root = new TreeNode(val);return;}//root不为空TreeNode cur = root;TreeNode parent = null;//找到cur为空的位置while (cur != null) {if (cur.val < val) {parent = cur;cur = cur.right;} else if (cur.val > val) {parent = cur;cur = cur.left;} else {return;}}//根据判断双亲结点的值来决定插入那个叶子结点TreeNode node = new TreeNode(val);if (val < parent.val) {parent.left = node;} else {parent.right = node;}}public void inorder(TreeNode root) {if (root == null) {return;}inorder(root.left);System.out.print(root.val + " ");inorder(root.right);}

3.二叉搜索树的删除

要删除的位置为cur,它的双亲结点为parent

  • 1.cur左结点为空:cur.left == null

    1.cur为根节点,cur没有左树,根节点移动到它的右树上

    2.cur不是根节点,此时cur为双亲结点的左结点,cur没有左树,双亲结点的左结点连上cur的右结点 parent.left = cur.right

    3.cur不是根节点,此时cur为双亲结点的右结点,cur没有左树,双亲结点的右结点连上cur的右结点 parent.right = cur.right

在这里插入图片描述

  • 2.cur右结点为空:cur.right == null

1.cur为根节点,cur没有右子树,根节点移动到cur的左子树上

2.cur不是根节点,cur是双亲结点的左结点,cur没有右结点,双亲结点的左结点连上cur的左结点

3.cur不是根节点,cur是双亲结点的右结点,cur没有右结点,双亲结点的右结点连上cur的左结点

在这里插入图片描述

3.左右结点都不为空:cur.left != null && cur.right != null

1.替换法进行删除,在cur的右子树中,找到该子树的最小值,和要删除的值交换

2.最后删除那个替换的结点,维护了二叉搜索树

3.替换的结点在它双亲结点的左边,没有左子树,target.left== nulll,如果有右子树,target双亲结点的左结点连接target的右结点(target的右结点都比target大),没有右子树,连接的是空值

4.替换的结点在它双亲结点的右边(双亲结点没有左结点),target双 亲结点的右结点连接target的右结点

在这里插入图片描述

/*** 删除值为val的结点** @param val* @return*/public void remove(int val) {TreeNode cur = root;TreeNode parent = null;//找到cur结点的位置while (cur != null) {if (cur.val == val) {removeNode(cur, parent);return;} else if (val < cur.val) {parent = cur;cur = cur.left;} else {parent = cur;cur = cur.right;}}}/*** 删除结点的分类情况** @param cur* @param parent*/private void removeNode(TreeNode cur, TreeNode parent) {if (cur.left == null) {//cur的左结点为空if (cur == root) {root = cur.right;} else if (cur == parent.left) {parent.left = cur.right;} else {parent.right = cur.right;}} else if (cur.right == null) {//cur的右结点为空if (cur == root) {root = cur.left;} else if (cur == parent.left) {parent.left = cur.left;} else {parent.right = cur.left;}} else {//cur的左右结点都不为空TreeNode target = cur.right;//在右树中找最小值TreeNode targetParent = cur;while (target.left != null) {targetParent = target;target = target.left;}//找最小值cur.val = target.val;//替换if (target == targetParent.left) {targetParent.left = target.right;//目标值在双亲结点的左边} else {targetParent.right = target.right;//目标值在双亲结点的右边}}}

4.性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能

  • 即结点越深,则比较次数越多
  • 插入的次序不同,可能得到不同结构的二叉搜索树

最好情况:二叉搜索树为完全二叉树,平均计较次数:log2N

最坏情况:二叉树退化成单分支树,平均比较次数为 N/2

  • 因为TreeSet和TreeMap的底层是红黑树,所以每次存储元素时,都得进行大小比较。所以存放到这两个集合类的数据,一定是可以比较的

点击移步博客主页,欢迎光临~

偷cyk的图

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

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

相关文章

7款前端实战型项目特效分享(附在线预览)

分享7款实用性的前端动画特效 其中有canvas特效、css动画、svg动画等等 下方效果图可能不是特别的生动 那么你可以点击在线预览进行查看相应的动画特效 同时也是可以下载该资源的 CSS春节灯笼特效 基于CSS实现的灯笼特效 灯笼会朝左右两个方向来回的摆动着 以下效果图只能体现…

关于Vue3的一些操作

1. 设置浏览器自动打开 在package.json 中设置 dev: vite --open 2.给src文件夹配置别名 在vite.config.ts配置文件中添加以下内容 3. 如果2中有红色波浪线的问题 ***安装一个文件包***npm install types/node3. 在tsconfig.json配置文件中&#xff0c;找到配置项compi…

Windows下Node.js安装保姆级教程

一、Node.js 下载 访问Node.js官网&#xff0c;点击下载Node.js 下载完成后即可在下载文件中查看安装包 二、安装 一&#xff09;点击安装包开始安装&#xff0c;进入Weclcome界面点击Next 二&#xff09;勾选同意协议&#xff0c;点击Next 三&#xff09;根据需要选择安装路…

Open CASCADE学习|表面着色显示模型

模型表面着色具有如下作用&#xff1a; 视觉增强&#xff1a;通过为模型表面添加着色&#xff0c;可以使其更加生动和逼真&#xff0c;提高视觉体验。 信息区分&#xff1a;在复杂的模型中&#xff0c;不同的部分或组件可能需要通过不同的颜色来区分&#xff0c;以便更清晰地…

简介maven核心:pom项目对象模型

Maven Maven 意思是知识的积累者&#xff0c;最初是为了简化 Jakarta Turbine 项目中的构建过程。有几个项目&#xff0c;每个项目都有自己的 Ant 构建文件&#xff0c;它们都略有不同。JAR 被检入 CVS。我们想要一种标准的方式来构建项目&#xff0c;清楚地定义项目的组成&am…

Redis缓存预热-缓存穿透-缓存雪崩-缓存击穿

什么叫缓存穿透? 模拟一个场景: 前端用户发送请求获取数据,后端首先会在缓存Redis中查询,如果能查到数据,则直接返回.如果缓存中查不到数据,则要去数据库查询,如果数据库有,将数据保存到Redis缓存中并且返回用户数据.如果数据库没有则返回null; 这个缓存穿透的问题就是这个…

电力物联网系统设计

电力物联网系统设计 简介 在新能源行业从业多年&#xff0c;参与和负责过大大小小的的项目&#xff0c;发电侧、电网侧、用户侧系统都有过实际的项目经验&#xff0c;这些项目或多或少都有物联网采集方面的需求&#xff0c;本篇文章将会对电力行业物联网经验做一个总结分享。 …

【Spring知识体系】1.1 Java 注解(Annotation)

文章目录 1.1 注解&#xff08;Annotation&#xff09;1.1.1 什么是注解1.1.2 内置注解1.1.3 元注解&#xff08;5种&#xff09;1.14 自定义注解1.15 注解使用场景介绍※ 本文小结 1.1 注解&#xff08;Annotation&#xff09; 1.1.1 什么是注解 注解的定义&#xff1a;它提…

基于工业边缘网关的机械状态监测与故障诊断应用

机械设备工作于各种各样的环境&#xff0c;在运行过程中必然受到力、温度、摩擦等多种物理、化学作用,使机械设备状态和性能变化,进而产生“隐性故障”。随着机械设备“隐性故障”的长期累积&#xff0c;可能造成设备损伤损坏&#xff0c;甚至影响系统整体生产和运营&#xff0…

从零开始学习Diffusion Models: Sharon Zhou

How Diffusion Models Work 本文是 https://www.deeplearning.ai/short-courses/how-diffusion-models-work/ 这门课程的学习笔记。 文章目录 How Diffusion Models WorkWhat you’ll learn in this course [1] Intuition[2] SamplingSetting Things UpSamplingDemonstrate i…

帮管客 CRM jiliyu SQL注入漏洞复现

0x01 产品简介 帮管客CRM是一款集客户档案、销售记录、业务往来等功能于一体的客户管理系统。帮管客CRM客户管理系统,客户管理,从未如此简单,一个平台满足企业全方位的销售跟进、智能化服务管理、高效的沟通协同、图表化数据分析帮管客颠覆传统,重新定义企业管理系统。 …

乐得瑞的一拖二100W智能分配方案更加成熟

在快节奏的现代生活中&#xff0c;手机不仅是通讯工具&#xff0c;更是我们工作、学习和娱乐的得力助手。然而&#xff0c;手机的电量问题一直是困扰我们的难题。为了解决这一问题&#xff0c;市场上应运而生了一种名为“一拖二快充线”的充电设备。它集快速充电与独特设计于一…

ADS功分器模型含义

ADS功分器模型含义 文章目录 ADS功分器模型含义dbpolar和单个值polar和单个值polar和dbpolar单个值 S21和S31传输系数 S11和S22反射系数 Isolation 隔离度 Zref 端口的参考阻抗&#xff0c;默认为50Ω CheckPassivity 检查是否无源&#xff0c;默认是无源器件 目前根据仿真结…

Shopify支持哪些付款方式 Shopify绑定信用卡教程

一、Shopify 信用卡和借记卡支付&#xff1a;Shopify支持Visa、Mastercard、American Express等国际信用卡和借记卡付款。卖家可以通过选择Fomepay的447420来付款 二、Shopify绑定信用卡教程 要在Shopify上绑定国内信用卡&#xff0c;需要进行以下步骤。 1、办理一张visa信…

Kafka MQ 生产者和消费者

Kafka MQ 生产者和消费者 Kafka 的客户端就是 Kafka 系统的用户&#xff0c;它们被分为两种基本类型:生产者和消费者。除 此之外&#xff0c;还有其他高级客户端 API——用于数据集成的 Kafka Connect API 和用于流式处理 的 Kafka Streams。这些高级客户端 API 使用生产者和消…

【Java】生成条形码工具类

报销单需要根据单号生成条形码 先看效果图 直接上代码&#xff0c;复制即可使用 /*** Description:生成条形码*/ public class BarCodeUtils {/*** 默认图片宽度*/private static final int DEFAULT_PICTURE_WIDTH 300;/*** 默认图片高度*/private static final int DEFAULT_…

一起来读李清照

当然先祝各位女生节日快乐&#x1f381;&#x1f381;啦​。​ 但是呢&#xff0c;今天&#xff0c;我们不聊技术&#xff0c;来聊点其他的。 大家都知道今天是三八妇女节&#xff0c;三八妇女节的是中国人的叫法&#xff0c;也叫国际妇女节。是为了纪念妇女权利的运动&#…

基于禁忌搜索算法(TS)的TSP(Python实现)

本篇文章是博主在最化优学习、人工智能等领域学习时&#xff0c;用于个人学习、研究或者欣赏使用&#xff0c;并基于博主对相关等领域的一些理解而记录的学习摘录和笔记&#xff0c;若有不当和侵权之处&#xff0c;指出后将会立即改正&#xff0c;还望谅解。文章分类在最优化算…

springboot248校园资产管理

校园资产管理 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本校园资产管理就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大…

CDN(内容分发网络):加速网站加载与优化用户体验

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…