【Java】二叉搜索树

文章目录

  • 一、搜索树
  • 二、使用代码实现一棵二叉搜索树
    • 1.查找
    • 2.插入
    • 3.删除(重点)
  • 总结


一、搜索树

二叉搜索树又称二叉排序树,它或者是一棵空树,或者是具有以下性质的二叉树:
若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
它的左右子树也分别为二叉搜索树

在这里插入图片描述
仔细观察上图,可以发现二叉搜索树的一个特性:
中序遍历二叉搜索树是有序的,所以二叉搜索树也被称为二叉排序树

二、使用代码实现一棵二叉搜索树

1.查找

遍历这棵树,先从树的根节点开始查找,如果树的根节点是我们要查找的元素就返回根节点,如果要查找的元素比我们的根节点小,就去树的左边寻找,如果比我们的根节点大就去树的右边寻找,直到遍历完整棵树为止

代码如下:

    public boolean search(int val) {TreeNode cur = root;while (cur != null) {//左树中去找if(cur.val > val) {cur = cur.left;//右树中去找}else if(cur.val < val) {cur = cur.right;}else {return true;}}return false;}

2.插入

往二叉搜索树插入一个元素的时候,我们要注意两点,首先如果二叉搜索树为空,则直接令 root 为当前插入的节点即可,如果不为空,则新的元素会依次与节点比较,如果比根节点大,则去根的右边,比根节点小,则去根的左边
首先定义一个 cur 引用,当 cur 等于 null 了,则表示是我要插入的位置,找到了要插入的位置,我们还得知道这个位置的父亲节点是谁,通过父亲节点将元素插入到该二叉树中

代码如下:

    public void insert(int val) {if(root == null) {root = new TreeNode(val);return;}TreeNode cur = root;//记录cur的上一个节点TreeNode parent = null;while (cur != null) {if(cur.val < val) {parent = cur;cur = cur.right;}else if(cur.val > val) {parent = cur;cur = cur.left;}else {return;}}//cur为空 将val插入到parent的左树或者右树TreeNode node = new TreeNode(val);if(parent.val > val) {parent.left = node;}else {parent.right= node;}}

3.删除(重点)

二叉搜索树中删除一个元素是很麻烦的,我们要把每一种情况都列举出来,而且在删除完一个元素后还要满足二叉搜素树的性质
设 cur 为要删除的元素,parent为待删除结点的双亲结点为,首先我们要判断这个二叉搜索树中,是否存在要删除的节点,这个方法在上面已经写过了,找到要删除的节点后,再对每一种情况进行删除:

1.cur没有左子树
cur 是 root,则 root = cur.right
cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
cur 不是 root,cur 是 parent.right,则 parent.right = cur.right
图解如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/d28ddf430aa74bb3bd781a311aae143b.pn
2.cur没有右子树
cur 是 root,则 root = cur.left
cur 不是 root,cur 是 parent.left,则 parent.left = cur.left
cur 不是 root,cur 是 parent.right,则 parent.right = cur.left
图解如下:
在这里插入图片描述
3.cur既有左子树又有右子树
使用替换法进行删除,即在 cur 的右子树中,一直往左寻找最小的元素,将这个最小值赋值给要删除节点的 val 值中,接着把这个最小元素的节点删除即可
图解如下:
在这里插入图片描述
在这里插入图片描述
代码如下:

    public void remove(int val) {TreeNode cur = root;TreeNode parent = null;while (cur != null) {if(cur.val < val) {parent = cur;cur = cur.right;}else if(cur.val > val) {parent = cur;cur = cur.left;}else {removeNode(parent,cur);return;}}}private void removeNode(TreeNode parent,TreeNode cur) {//左树为空if(cur.left == null) {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) {if(cur == root) {root = cur.left;}else if(cur == parent.left) {parent.left = cur.left;}else {parent.right = cur.left;}//两个都不为空  使用替换法的方式来删除节点}else {TreeNode t = cur.right;TreeNode tp = cur;while (t.left != null) {tp = t;t = t.left;}cur.val = t.val;if(tp.left == t) {tp.left = t.right;}else {tp.right = t.right;}}}

总结

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多
二叉搜索树在最好的情况下为完全二叉树,查找的平均比较次数为:logn
二叉搜索树在最差的情况下退化成但分支,查找的平均比较次数为:n/2
注意:
二叉搜索树不要求是完全二叉树或满二叉树,甚至会出现单分支的二叉搜索树,所以针对这种特殊的情况进行了优化也就延申出了 AVL树,当发现二叉搜索树左右子树高度差太大,会自动旋转,以致平衡,避免旋转的次数太多,又引入了红黑树,给节点增加了颜色,细节部分后期讲解,这里有个概念即可

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

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

相关文章

练习 12 Web [极客大挑战 2019]BabySQL

本题复习&#xff1a;1.常规的万能语句SQL查询&#xff0c;union联合查询&#xff0c;Extractvalue()报错注入 extractvalue(1,concat(‘0x7e’,select(database())))%23 我一开始挨着试&#xff0c;感觉都无效 直到报错注入&#xff0c;查到了库名‘geek’ 尝试查表名&…

Ubuntu下采用VSCode调试C/C++ (1)

对于如何在VSCode上调试C/C&#xff0c;网上已经有足够多的方案&#xff0c;主要是在VSCode上安装&#xff1a;C/C拓展和Code Runner&#xff0c;以及launch.json、tasks.json及c_cpp_properties.json相关的配置。 但是&#xff0c;按照网上的一套操作之后却运行不起来&#xf…

重新配置node.js,npm,环境变量

起因是检查最近收到的一些朋友分享给我的各种资料&#xff0c;什么前端&#xff0c;后端&#xff0c;java,go,python等语言&#xff0c;想着将一个模拟QQ音乐的一个源代码进行跑通&#xff0c;看看有什么特别之处。如下图 出现了node环境路径问题&#xff0c;参考链接 https:/…

使用CSS3画出一个叮当猫HTML源码

我们经常使用PS或者Flash制作动画&#xff0c;本文则介绍了如何用CSS3画出个叮当猫&#xff0c;实现过程很有趣&#xff0c;感兴趣的朋友可以参考一下 首先&#xff0c;先把HTML结构搭建好&#xff1a; <div class"wrapper"> <!--叮当猫整体--> <di…

Java中的Stream流

一、介绍 1. Stream流的作用 结合了Lambda表达式&#xff0c;简化集合、数组的操作。 2. Stream流的使用步骤 ①先得到一条Stream流&#xff0c;并把数据放上去&#xff1b; 获取方式方法名说明单列集合default Stream<E> stream()Collection中的默认方法双列集合无无…

【ubuntu的python报错】/usr/bin/env: “python3\r”: 没有那个文件或目录

【ubuntu的python报错】/usr/bin/env: “python3\r”: 没有那个文件或目录 通过apt-get命令安装dos2unix的包&#xff0c;然后通过dos2unix这个命令即可完成转换。 通过apt-get命令安装dos2unix的包&#xff0c;然后通过dos2unix这个命令即可完成转换。 sudo apt-get install …

git -- 提交规范

参考链接 – 1 参考链接 – 2 参考链接 – 3 以下常见的Git代码提交规范,可以根据团队的具体情况进行调整和补充。重要的是,团队成员要保持一致性,遵守代码提交规范,以便更好地协作和维护代码库。 为什么使用同一提交代码规范有如下原因: 自动化生成 CHANGELOG。基于提交的…

是德科技keysight N1912A双通道功率计

181/2461/8938产品概述&#xff1a; Keysight(原Agilent) N1912A P系列双通道功率计可提供峰值、峰均比、平均功率、上升时间、下降时间、最大功率值、最小功率值以及宽带信号的统计数据。 Keysight(原Agilent) N1912A P系列双通道功率计, 可提供峰值、峰均比、平均功率、上升…

Redis安装详细教程

Redis安装详细教程 文章目录 Redis安装详细教程前言一、windows下安装Redis1、下载地址2、启动redis服务3、连接redis 二、Linux下安装Redis&#xff1a;直接安装1、下载并安装 三、Linux下安装Redis&#xff1a;Docker中安装 前言 一、windows下安装Redis 1、下载地址 官方下…

Docker 容器中运行 JAR 文件的方法

由于 Docker 容器通常需要一个操作系统级环境来运行应用程序&#xff0c;而 JAR 文件&#xff08;Java ARchive&#xff09;是一个包含 Java 应用程序或库的文件&#xff0c;需要 Java 运行时环境&#xff08;JRE&#xff09;来执行。 以下是运行 JAR 文件的基本步骤&#xff…

冒泡排序,选择排序,插入排序,希尔排序,堆排序,快速排序的递归版。(直接可用,懒人必备)。

注意&#xff1a;1.在使用前需要先将Swap函数放在最前面。基本上都用了了Swap函数。 2.完成的是升序版本&#xff0c;如想逆序&#xff0c;自行更改。 目录 Swap函数&#xff1a; 冒泡排序&#xff1a; 选择排序 插入排序 希尔排序 堆排序 快速排序 Swap函数&#xff1a…

Vue 3项目中结合Element Plus的<el-menu>和CSS3创建锚点,以实现点击菜单项时平滑滚动到对应的锚点目标

安装Element Plus&#xff1a; 确保已经安装了Element Plus库。可以使用npm或者yarn进行安装&#xff0c;具体步骤与上文提到的相同。 引入Element Plus&#xff1a; 在你的Vue 3项目中引入所需的Element Plus组件和样式。 创建el-menu&#xff1a; 在Vue组件中使用<el-me…

Unity发布webgl之后打开PDF文件,不使用js,不和浏览器交互

创建一个按钮&#xff0c;然后点击就会打开 在webgl下要使用这样的路径拼接&#xff0c;不然就会报错。 btnBook.onClick.AddListener(() >{var uri new System.Uri(Path.Combine(Application.streamingAssetsPath "/Books", "文档.pdf"));Debug.Log…

PyTorch深度学习:如何实现遥感影像的自动化地物分类?

我国高分辨率对地观测系统重大专项已全面启动&#xff0c;高空间、高光谱、高时间分辨率和宽地面覆盖于一体的全球天空地一体化立体对地观测网逐步形成&#xff0c;将成为保障国家安全的基础性和战略性资源。未来10年全球每天获取的观测数据将超过10PB&#xff0c;遥感大数据时…

前端根据pdf连接点击下载pdf而不是直接打开

参考地址: https://www.cnblogs.com/jackson-yqj/p/11321275.html /*** 文件链接转文件流下载--主要针对pdf 解决谷歌浏览器a标签下载pdf直接打开的问题* param url &#xff1a;文件链接* param fileName &#xff1a;文件名;* param type &#xff1a;文件类型;*/functio…

Azure databricks spark overwrite 全量更新的时候容易碰到的问题

原因&#xff1a;Azure databricks spark overwrite 全量ADS层表更新的时候容易碰到的问题正在写入结果有服务请求这个表的数据那如何避免呢&#xff1f; 1、 databricks spark overwrite 到的的时候会先TRUNCATE TABLE 然后再写入&#xff0c;就会碰到查询是空的情况&#xff…

Prompt进阶系列4:LangGPT(构建高性能Prompt实践指南)--结构化Prompt

Prompt进阶系列4:LangGPT(构建高性能Prompt实践指南)–结构化Prompt 1.结构化 Prompt简介 结构化的思想很普遍&#xff0c;结构化内容也很普遍&#xff0c;我们日常写作的文章&#xff0c;看到的书籍都在使用标题、子标题、段落、句子等语法结构。结构化 Prompt 的思想通俗点…

从零开始学Spring Boot系列-集成Kafka

Kafka简介 Apache Kafka是一个开源的分布式流处理平台&#xff0c;由LinkedIn公司开发和维护&#xff0c;后来捐赠给了Apache软件基金会。Kafka主要用于构建实时数据管道和流应用。它类似于一个分布式、高吞吐量的发布-订阅消息系统&#xff0c;可以处理消费者网站的所有动作流…

[音视频学习笔记]七、自制音视频播放器Part2 - VS + Qt +FFmpeg 写一个简单的视频播放器

前言 话不多说&#xff0c;重走霄骅登神路 前一篇文章 [音视频学习笔记]六、自制音视频播放器Part1 -新版本ffmpeg&#xff0c;Qt VS2022&#xff0c;都什么年代了还在写传统播放器&#xff1f; 本文相关代码仓库&#xff1a; MediaPlay-FFmpeg - Public 转载雷神的两个流程…

常用的IDE推荐

程序员在选择集成开发环境&#xff08;IDE&#xff09;时&#xff0c;会考虑多种因素&#xff0c;包括易用性、功能丰富性、性能以及是否支持他们正在使用的编程语言。以下是一些建议的IDE及其优点&#xff1a; 1.JetBrains PyCharm&#xff1a;专为Python开发而设计的IDE。 优…