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

文章目录

    • 一、搜索树
      • 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.hqwc.cn/news/521648.html

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

相关文章

要更好地理解世界

要更好地理解世界&#xff0c;我们可以采用以下思维方式&#xff1a; 批判性思维&#xff08;critical thinking&#xff09;&#xff1a;批判性思维是一种理性、明确和公正的思考方式&#xff0c;它可以帮助我们识别和分析问题、评估证据和论据&#xff0c;以及在做决策或解决…

​谷歌seo外链还有用吗?

这么说吧&#xff0c;一个网站的外部建设&#xff0c;外链就是谷歌最重要的评判标准之一&#xff0c;至少在你想做谷歌seo&#xff0c;外链的建设绝对是绕不开的一个坎&#xff0c;只靠网站本身终究是有上限的&#xff0c;一个没有任何外链的网站&#xff0c;谷歌是很难信任你的…

设计模式:六大原则 ③

一、六大设计原则 &#x1f360; 开闭原则 (Open Close Principle) &#x1f48c; 对扩展开放&#xff0c;对修改关闭。在程序需要进行拓展的时候&#xff0c;不能去修改原有的代码&#xff0c;实现一个热插拔的效果。简言之&#xff0c;是为了使程序的扩展性好&#xff0c;易…

NASA数据集——Two-Dimensional Video Disdrometer (2DVD)二维视频测距仪 (2DVD)数据集

简介 Two-Dimensional Video Disdrometer (2DVD) 测距仪是一种安装在固定地面站平台上的光学设备&#xff0c;用于测量不同类型水文流星&#xff08;降水&#xff09;的特性&#xff0c;如雨滴、雪花和冰雹。二维视频测距仪 (2DVD) 使用两台高速线扫描照相机对所有降水颗粒和…

VR全景技术在VR看房中有哪些应用,能带来哪些好处

引言&#xff1a; 随着科技的不断发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术在房地产行业中的应用也越来越广泛。其中&#xff0c;VR全景技术在VR看房中的运用尤为突出。今天&#xff0c;让我们一起深入探讨VR全景技术在VR看房中的应用及其带来的种种好处。 一、…

StarRocks实战——欢聚集团极速的数据分析能力

目录 一、大数据平台架构 二、OLAP选型及改进 三、StarRocks 经验沉淀 3.1 资源隔离&#xff0c;助力业务推广 3.1.1 面临的挑战 3.1.2 整体效果 3.2 稳定优先&#xff0c;监控先行&#xff0c;优化运维 3.3降低门槛&#xff0c;不折腾用户 3.3.1 与现有的平台做打通 …

sqlyog社区版下载,数据库客户端,mysql

Downloads webyog/sqlyog-community Wiki GitHubhttps://github.com/webyog/sqlyog-community/wiki/Downloadssqlyog社区版下载

降本增效大环境下-十行代码让日志存储降低80%

日志是系统中熵增最快的一个模块&#xff0c;它承载了业务野蛮生长过程中的所有副产品。本文介绍了一个日志治理案例&#xff0c;围绕降本和提效两大主题&#xff0c;取得一定成效&#xff0c;分享给所有渴望造物乐趣的同学。 前言 履约管理是一个面向物流商家的OMS工作台&am…

浏览器修改接口返回数据展示在页面上

前端自己调试&#xff0c;想修改接口返回来的数据&#xff0c;然后展示在页面上 举例 接口返回了数据&#xff0c;想要修改此数据 这时就可以修改数据了&#xff0c;修改完成保存 然后刷新页面就会使用本地保存的数据了

【数据分享】2000-2022年全国1km分辨率的逐月PM2.5栅格数据(免费获取)

PM2.5作为最主要的空气质量指标&#xff0c;在我们日常研究中非常常用&#xff01;之前我们给大家分享了2013-2022年全国范围逐日的PM2.5栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01; 本次我们给大家带来的是2000-2022年全国范围的逐月的PM2.5栅格数…

基于单片机的水平角度仪系统设计

目 录 摘 要 I Abstract II 引 言 1 1控制系统设计 3 1.1系统方案设计 3 1.2系统工作原理 4 2硬件设计 6 2.1单片机 6 2.1.1单片机最小系统 6 2.1.2 STC89C52单片机的性能 7 2.2角度采集电路 8 2.2.1 ADXL345传感器的工作原理 9 2.2.2 ADXL345传感器倾角测量的原理 9 2.2.3 AD…

App自动化测试笔记(十一):综合案例

短信案例 需求 在《短信》应用中&#xff0c;进入发送短信页面&#xff0c;在姓名和内容栏中&#xff0c;输入对应的数据&#xff0c;并点击发送。 包名界面名&#xff1a;com.android.mms/.ui.ConversationList 发送短信页面标识&#xff1a;resource-id&#xff0c;com.and…