当前位置: 首页 > news >正文

JAVA-数据结构- 二叉搜索树

1.搜索树

 前面我们已经使用C语言学习完了二叉树,懂得了一些二叉树的基本性质已经实现方法 icon-default.png?t=O83Ahttps://mp.csdn.net/mp_blog/creation/editor/139572374,本文我们来一起进行二叉树的衍生-二叉搜索树

1.1 概念


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

简单来说,就是给二叉树定义为左右节点,左子树比根节点小,右子树比根节点大

 

1.2简单实现二叉搜索树的增加和删除

1.2.1创建二叉搜索树

 1.首先在搜索树内定义一个静态类来表示初始二叉树 ,定义出右指针,左指针,根节点,其他的交给二叉树的增加即可

 static class TreeNode{//在类中使用一个整体类来表示二叉树,要用静态类int val;TreeNode left;TreeNode right;public TreeNode(int val) {this.val = val;}}public TreeNode root;//定义根节点

2.判断输入值是否存在搜索树中

将输入的值和根节点比较,大于就将根节点向右移,小于就将根节点的值向左移,直到找到为止,找不到就返回false.

 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;}

1.2.2向二叉搜索树内添加元素

首先进行判空,将要赋值的数放在二叉树类里

1.判断要添加的值要放在哪,和判断是否存在一个道理,但是需要找到根节点的上一个指针,方便插入。

比方说我们要在这么个搜索二叉树内插入4

1.   4比5小,所以往左走,

2.   4比3大,所以往右走,发现cur为空,则停止

3.  将parent.right 赋值为4

 public void insert(int val){//二叉搜索树的添加TreeNode noot = new TreeNode(val);if(root == null){root = noot;//若为空,添加进来的元素则为根节点return;}TreeNode parent = null;//负责记录cur的上一个指针TreeNode cur = root;while(cur!=null){//若cur为零则说明parent的左指针或者右指针已经为插入位置if(val>cur.val){parent = cur;cur = cur.right;}else if(val<cur.val){parent = cur;cur = cur.left;}else{return;//如果找到就没必要添加了}}if(val>parent.val){parent.right=noot;//此时cur是叶子节点,所以需要有parent这个变量}else {parent.left = noot;}}

 1.2.3删除搜索树内的元素(难点)

思路:首先得先找到删除节点的位置  然后我们将删除分为三种情况:

1.删除的元素的左子树 == null

1.1  cur == root

当需要删除的元素在根节点时,直接将根节点右子树改为根节点即可

root = cur.right;

1.2  cur == parent.right

 parent.right = cur.right

由图可得, 

1.3cur == parent.left

parent.left = cur.right 

2.删除的元素的右子树 == null(和上面一样)

1.1  cur == root

1.2  cur == parent.right

1.3cur == parent.left

3.删除的元素左子树 == null && 右子树 == null(难点)

这时我们可以采用替换法,找到搜索树中同样适合放在删除位置的元素进行交换

这时 我们可以把左子树的最大值找到,也可以将右子树的最小值找到

 此时我们在删除的时候可能会面对以下情况

我们发现cur == 10的情况可以和9,15进行交换,此时我们任选一个即可

接下来我就统一使用找右子树最小值来写,找右子树的最小值,一定是根节点的左子树,所以我们需要找target.left == null的位置,此时target为cur右子树的最小值

其中,target负责找到最小值的位置,targetParent负责给target擦屁股,连接target的右子树

首先,将target定义为cur.right,targetParent = cur

然后遍历搜索树找到替换节点 

 然后将target位置的值给到cur

 

targetParent.left指向target.right

 记得考虑特殊情况

target一开始就没有left

 

所以找到替换位置后需要判断target和targetParent的位置关系

当 target在targetParent右边时需要特殊处理

删除总代码实现

 public void remove(int key) {TreeNode cur = root;TreeNode parent = null;while (cur != null) {if(cur.val < key) {parent = cur;cur = cur.right;}else if(cur.val > key) {parent = cur;cur = cur.left;}else {removeNode(cur,parent);//找到需要删除的位置return;}}}public void removeNode(TreeNode cur,TreeNode parent){if(cur.left == null){if(cur == root){//当根节点为删除点时root = cur.right;}else if(cur == parent.left){//当cur是parent的左节点parent.left = cur.right;}else{//当cur是parent的右节点parent.right = cur.right;}}else if(cur.right == null){if(cur == root) {//当根节点为删除点时root = cur.left;}else if(parent.left == cur){//当cur是parent的右节点parent.left = cur.left;}else {//当cur是parent的左节点parent.right = cur.left;}}else{TreeNode target = cur.right,targetparent = cur;//targetParent是为了方便替换后,直接连接下一个节点while(target.left!=null){targetparent = target;target = target.left;}cur.val = target.val;//将替换值赋值给需要删除位置的值if(targetparent.right == target) {//对一开始就没有left的target进行特殊处理targetparent.right = target.right;}else {targetparent.left = target.right;}}

1.3性能分析

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

最好情况:最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:log2 **n

最坏情况:单分支二叉树其平均比较次数为:n/2

相关文章:

JAVA-数据结构- 二叉搜索树

1.搜索树 前面我们已经使用C语言学习完了二叉树&#xff0c;懂得了一些二叉树的基本性质已经实现方法 https://mp.csdn.net/mp_blog/creation/editor/139572374&#xff0c;本文我们来一起进行二叉树的衍生-二叉搜索树 1.1 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是…...

深入研究 RAG 流程中的关键组件

我们已经看到了整个RAG流程&#xff0c;并获得了第一手的实践经验&#xff0c;您可能会对RAG流程中一些组件的使用和目的存在很多疑惑&#xff0c;比如RunnablePassthrough。在本节中&#xff0c;我们将进一步了解这些关键组件。 RAG的核心模型思想是将一个复杂的任务分解为多…...

新手如何学习python并快速成为高手

英雄Python入门到精通链接&#xff1a;https://pan.quark.cn/s/57162ec366a9 学习Python作为新手&#xff0c;有以下几个步骤&#xff1a; 学习基本概念和语法&#xff1a;首先&#xff0c;你需要学习Python的基本概念和语法。可以通过在线教程、书籍或者视频教程来学习。了解…...

Linux历史命令history增加执行时间显示

Centos系统默认历史命令显示如下 为了更好的溯源&#xff0c;获取执行命令的准确时间&#xff0c;需要增加一些配置 设置环境变量 vim /etc/profile 在最下面添加以下环境配置 export HISTTIMEFORMAT"%Y-%m-%d %H:%M:%S " 立即刷新该环境变量 source /etc/pro…...

从 vue 源码看问题 — 你知道 Hook Event 吗?

前言 在之前的几篇文章中&#xff0c;都有提到 vue 中调用生命周期钩子时是通过 callHook() 方法进行调用的&#xff0c;比如在初始化篇章中调用 beforeCreate 和 created 生命周期钩子方式如下: 那么接下来一起来了解下到底什么是 Hook Event &#xff1f; Hook Event 是什…...

信息安全工程师(68)可信计算技术与应用

前言 可信计算技术是一种计算机安全体系结构&#xff0c;旨在提高计算机系统在面临各种攻击和威胁时的安全性和保密性。 一、可信计算技术的定义与原理 可信计算技术通过包括硬件加密、受限访问以及计算机系统本身的完整性验证等技术手段&#xff0c;确保计算机系统在各种攻击和…...

每日OJ题_牛客_相差不超过k的最多数_滑动窗口_C++_Java

目录 牛客_相差不超过k的最多数_滑动窗口 题目解析 C代码 Java代码 牛客_相差不超过k的最多数_滑动窗口 相差不超过k的最多数_牛客题霸_牛客网 (nowcoder.com) 描述&#xff1a; 给定一个数组&#xff0c;选择一些数&#xff0c;要求选择的数中任意两数差的绝对值不超过 …...

来咯来咯webSocket

在项目总目录下 设置socketServe文件夹 里面创建下面两个文件 使用的时候需要开启 node webSocket.cjs var { Server } require(ws); var moment require(moment);const wss new Server({port: 8888 });let id 0; let onlineMemberList []; const defaultUser user;wss…...

Android CALL关于电话音频和紧急电话设置和获取

获取音频服务&#xff0c;设置音源类型&#xff1a;电话类型和获取最大电话音量&#xff0c;响铃模式 private AudioManager mAudioManager; mAudioManager (AudioManager) getSystemService(AUDIO_SERVICE); mAudioManager.setStreamVolume(AudioManager.STREAM_VOIC…...

【春秋云镜】CVE-2023-23752

目录 CVE-2023-23752漏洞细节漏洞利用示例修复建议 春秋云镜&#xff1a;解法一&#xff1a;解法二&#xff1a; CVE-2023-23752 是一个影响 Joomla CMS 的未授权路径遍历漏洞。该漏洞出现在 Joomla 4.0.0 至 4.2.7 版本中&#xff0c;允许未经认证的远程攻击者通过特定 API 端…...

C#-__DynamicallyInvokable

[__DynamicallyInvokable] 属性是用于 .NET Framework 中的特性之一。这个特性通常用于标记在动态语言运行时中可以进行调用的方法或属性。 当一个方法或属性被标记为 [__DynamicallyInvokable]&#xff0c;它表明这个成员在动态语言的环境中是可调用的。换句话说&#xff0c;…...

2024年最新10款顶级项目管理软件排行

项目管理软件在现代项目管理中扮演着至关重要的角色&#xff0c;它不仅仅是一个工具&#xff0c;更是一种高效、系统化的方法来管理和优化项目流程&#xff0c;帮助项目经理和团队成员快速了解项目状态&#xff0c;加速项目进展。 进度猫 进度猫是一款以甘特图为向导的轻量级…...

Python NLTK进阶:深入自然语言处理

目录 Python NLTK进阶&#xff1a;深入自然语言处理 1. 文本处理技术 1.1 命名实体识别&#xff08;NER&#xff09; 1.2 共指消解 2. 语义分析 2.1 语义角色标注&#xff08;SRL&#xff09; 2.2 词义消歧&#xff08;Word Sense Disambiguation&#xff09; 3. 机器学…...

【React 的理解】

谈一谈你对 React 的理解 对待这类概念题&#xff0c;讲究一个四字口诀“概用思优”&#xff0c;即“讲概念&#xff0c;说用途&#xff0c;理思路&#xff0c;优缺点&#xff0c;列一遍” 。 React 是一个网页 UI 框架&#xff0c;通过组件化的方式解决视图层开发复用的问题&a…...

软件压力测试有多重要?北京软件测试公司有哪些?

软件压力测试是一种基本的质量保证行为&#xff0c;它是每个重要软件测试工作的一部分。压力测试是给软件不断加压&#xff0c;强制其在极限的情况下运行&#xff0c;观察它可以运行到何种程度&#xff0c;从而发现性能缺陷。 在数字化时代&#xff0c;用户对软件性能的要求越…...

十四届蓝桥杯STEMA考试Python真题试卷第二套第五题

来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第五题 本题属于迷宫类问题,适合用DFS算法解决,解析中给出了Python中 map() 和列表推导式的应用技巧。最后介绍了DFS算法的两种常见实现方式——递归实现、栈实现,应用场景——迷宫类问题、图的连通性、树的遍历、拓朴排…...

虚拟机 Ubuntu 扩容

文章目录 一、Vmware 重新分配 Ubuntu 空间二、Ubuntu 扩容分区 一、Vmware 重新分配 Ubuntu 空间 先打开 Vmware &#xff0c;选择要重新分配空间的虚拟机 点击 编辑虚拟机设置 &#xff0c;再点击 硬盘 &#xff0c;再点击 扩展 选择预计扩展的空间&#xff0c;然后点击 扩展…...

内网远程连接解决方案【Frp】

1、从https://github.com/fatedier/frp/releases下载需要的版本&#xff0c;如 frp_0.61.0_linux_amd64.tar.gz 2、解压tar -xvf frp_0.61.0_linux_amd64.tar.gz 3、配置服务端【外网云主机】&#xff0c;修改ftps.toml文件&#xff1a; bindPort 7000 vhostHTTPPort8000…...

浙江欧瑞雅装饰材料有限公司:空间的艺术,定制的智慧!

浙江欧瑞雅装饰材料有限公司&#xff1a;空间的艺术&#xff0c;定制的智慧&#xff01;在追求生活品质与空间利用并重的当下&#xff0c;浙江欧瑞雅装饰材料有限公司以其卓越的全屋定制服务&#xff0c;成为了众多家庭优化居住环境的理想选择。这家公司&#xff0c;凭借其深厚…...

jfrog artifactory oss社区版,不支持php composer私库

一、docker安装 安装环境&#xff1a;centos操作系统&#xff0c;root用户。 如果是mac或ubuntu等操作系统的话&#xff0c;会有许多安装的坑等着你。 一切都是徒劳&#xff0c;安装折腾那么久&#xff0c;最后还是不能使用。这就是写本文的初衷&#xff0c;切勿入坑就对了。 …...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

nnUNet V2修改网络——暴力替换网络为UNet++

更换前,要用nnUNet V2跑通所用数据集,证明nnUNet V2、数据集、运行环境等没有问题 阅读nnU-Net V2 的 U-Net结构,初步了解要修改的网络,知己知彼,修改起来才能游刃有余。 U-Net存在两个局限,一是网络的最佳深度因应用场景而异,这取决于任务的难度和可用于训练的标注数…...

GraphQL 实战篇:Apollo Client 配置与缓存

GraphQL 实战篇&#xff1a;Apollo Client 配置与缓存 上一篇&#xff1a;GraphQL 入门篇&#xff1a;基础查询语法 依旧和上一篇的笔记一样&#xff0c;主实操&#xff0c;没啥过多的细节讲解&#xff0c;代码具体在&#xff1a; https://github.com/GoldenaArcher/graphql…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...