JAVA-数据结构- 二叉搜索树
1.搜索树
前面我们已经使用C语言学习完了二叉树,懂得了一些二叉树的基本性质已经实现方法
https://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语言学习完了二叉树,懂得了一些二叉树的基本性质已经实现方法 https://mp.csdn.net/mp_blog/creation/editor/139572374,本文我们来一起进行二叉树的衍生-二叉搜索树 1.1 概念 二叉搜索树又称二叉排序树,它或者是…...
深入研究 RAG 流程中的关键组件
我们已经看到了整个RAG流程,并获得了第一手的实践经验,您可能会对RAG流程中一些组件的使用和目的存在很多疑惑,比如RunnablePassthrough。在本节中,我们将进一步了解这些关键组件。 RAG的核心模型思想是将一个复杂的任务分解为多…...
新手如何学习python并快速成为高手
英雄Python入门到精通链接:https://pan.quark.cn/s/57162ec366a9 学习Python作为新手,有以下几个步骤: 学习基本概念和语法:首先,你需要学习Python的基本概念和语法。可以通过在线教程、书籍或者视频教程来学习。了解…...
Linux历史命令history增加执行时间显示
Centos系统默认历史命令显示如下 为了更好的溯源,获取执行命令的准确时间,需要增加一些配置 设置环境变量 vim /etc/profile 在最下面添加以下环境配置 export HISTTIMEFORMAT"%Y-%m-%d %H:%M:%S " 立即刷新该环境变量 source /etc/pro…...
从 vue 源码看问题 — 你知道 Hook Event 吗?
前言 在之前的几篇文章中,都有提到 vue 中调用生命周期钩子时是通过 callHook() 方法进行调用的,比如在初始化篇章中调用 beforeCreate 和 created 生命周期钩子方式如下: 那么接下来一起来了解下到底什么是 Hook Event ? Hook Event 是什…...
信息安全工程师(68)可信计算技术与应用
前言 可信计算技术是一种计算机安全体系结构,旨在提高计算机系统在面临各种攻击和威胁时的安全性和保密性。 一、可信计算技术的定义与原理 可信计算技术通过包括硬件加密、受限访问以及计算机系统本身的完整性验证等技术手段,确保计算机系统在各种攻击和…...
每日OJ题_牛客_相差不超过k的最多数_滑动窗口_C++_Java
目录 牛客_相差不超过k的最多数_滑动窗口 题目解析 C代码 Java代码 牛客_相差不超过k的最多数_滑动窗口 相差不超过k的最多数_牛客题霸_牛客网 (nowcoder.com) 描述: 给定一个数组,选择一些数,要求选择的数中任意两数差的绝对值不超过 …...
来咯来咯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关于电话音频和紧急电话设置和获取
获取音频服务,设置音源类型:电话类型和获取最大电话音量,响铃模式 private AudioManager mAudioManager; mAudioManager (AudioManager) getSystemService(AUDIO_SERVICE); mAudioManager.setStreamVolume(AudioManager.STREAM_VOIC…...
【春秋云镜】CVE-2023-23752
目录 CVE-2023-23752漏洞细节漏洞利用示例修复建议 春秋云镜:解法一:解法二: CVE-2023-23752 是一个影响 Joomla CMS 的未授权路径遍历漏洞。该漏洞出现在 Joomla 4.0.0 至 4.2.7 版本中,允许未经认证的远程攻击者通过特定 API 端…...
C#-__DynamicallyInvokable
[__DynamicallyInvokable] 属性是用于 .NET Framework 中的特性之一。这个特性通常用于标记在动态语言运行时中可以进行调用的方法或属性。 当一个方法或属性被标记为 [__DynamicallyInvokable],它表明这个成员在动态语言的环境中是可调用的。换句话说,…...
2024年最新10款顶级项目管理软件排行
项目管理软件在现代项目管理中扮演着至关重要的角色,它不仅仅是一个工具,更是一种高效、系统化的方法来管理和优化项目流程,帮助项目经理和团队成员快速了解项目状态,加速项目进展。 进度猫 进度猫是一款以甘特图为向导的轻量级…...
Python NLTK进阶:深入自然语言处理
目录 Python NLTK进阶:深入自然语言处理 1. 文本处理技术 1.1 命名实体识别(NER) 1.2 共指消解 2. 语义分析 2.1 语义角色标注(SRL) 2.2 词义消歧(Word Sense Disambiguation) 3. 机器学…...
【React 的理解】
谈一谈你对 React 的理解 对待这类概念题,讲究一个四字口诀“概用思优”,即“讲概念,说用途,理思路,优缺点,列一遍” 。 React 是一个网页 UI 框架,通过组件化的方式解决视图层开发复用的问题&a…...
软件压力测试有多重要?北京软件测试公司有哪些?
软件压力测试是一种基本的质量保证行为,它是每个重要软件测试工作的一部分。压力测试是给软件不断加压,强制其在极限的情况下运行,观察它可以运行到何种程度,从而发现性能缺陷。 在数字化时代,用户对软件性能的要求越…...
十四届蓝桥杯STEMA考试Python真题试卷第二套第五题
来源:十四届蓝桥杯STEMA考试Python真题试卷第二套编程第五题 本题属于迷宫类问题,适合用DFS算法解决,解析中给出了Python中 map() 和列表推导式的应用技巧。最后介绍了DFS算法的两种常见实现方式——递归实现、栈实现,应用场景——迷宫类问题、图的连通性、树的遍历、拓朴排…...
虚拟机 Ubuntu 扩容
文章目录 一、Vmware 重新分配 Ubuntu 空间二、Ubuntu 扩容分区 一、Vmware 重新分配 Ubuntu 空间 先打开 Vmware ,选择要重新分配空间的虚拟机 点击 编辑虚拟机设置 ,再点击 硬盘 ,再点击 扩展 选择预计扩展的空间,然后点击 扩展…...
内网远程连接解决方案【Frp】
1、从https://github.com/fatedier/frp/releases下载需要的版本,如 frp_0.61.0_linux_amd64.tar.gz 2、解压tar -xvf frp_0.61.0_linux_amd64.tar.gz 3、配置服务端【外网云主机】,修改ftps.toml文件: bindPort 7000 vhostHTTPPort8000…...
浙江欧瑞雅装饰材料有限公司:空间的艺术,定制的智慧!
浙江欧瑞雅装饰材料有限公司:空间的艺术,定制的智慧!在追求生活品质与空间利用并重的当下,浙江欧瑞雅装饰材料有限公司以其卓越的全屋定制服务,成为了众多家庭优化居住环境的理想选择。这家公司,凭借其深厚…...
jfrog artifactory oss社区版,不支持php composer私库
一、docker安装 安装环境:centos操作系统,root用户。 如果是mac或ubuntu等操作系统的话,会有许多安装的坑等着你。 一切都是徒劳,安装折腾那么久,最后还是不能使用。这就是写本文的初衷,切勿入坑就对了。 …...
从黑猩猩内战到人类关系:互动是系统的命脉,遗忘是文明的暗礁
从黑猩猩内战到人类关系:互动是系统的命脉,遗忘是文明的暗礁 将黑猩猩Ngogo群体从平和共处走向相互屠戮的演变过程,结合人类关系分型自相似性理论对照分析,一套完整的认知逻辑就此显现。江河支流汇聚、树木枝杈生长,乃…...
从集合运算到代码:一文搞懂Jaccard系数,附Python/NumPy/Pandas三种实现方法对比
从集合运算到代码:一文搞懂Jaccard系数,附Python/NumPy/Pandas三种实现方法对比在数据挖掘和机器学习领域,衡量两个集合的相似度是一项基础而重要的任务。Jaccard相似系数作为一种简单直观的度量方法,广泛应用于推荐系统、文本挖掘…...
信息安全工程师-大数据安全核心知识点与备考指南-终章
一、引言大数据是指具备 4V 核心特性的大规模数据集合,其安全是软考信息安全工程师考试中网络安全与应用安全领域的新兴核心考点,在近年考试中分值占比逐年提升至 8%-12%。大数据技术的发展历经三个里程碑阶段:2006 年 Hadoop 框架发布标志着…...
深度剖析Claude Code实操逻辑,解锁AI编程高效开发方式
文章目录前言一、我用Claude Code的翻车现场,能写一本《程序员血泪史》二、Claude Code的核心设计思想:你以为它是保姆,其实它是保安三、普通模式vs规划模式:一个是临时工,一个是项目经理四、两条核心指令,…...
ChatGPT记忆功能安全风险预警,3大数据泄露漏洞已验证(附GDPR/等保2.0合规配置清单)
更多请点击: https://codechina.net 第一章:ChatGPT记忆功能怎么用 ChatGPT 的记忆功能(Memory)是 OpenAI 为 Plus 用户提供的个性化上下文增强能力,它允许模型在跨会话中记住用户提供的关键信息,并在后续…...
Nacos CVE-2021-29442:Spring Boot Actuator未授权访问漏洞深度解析
1. 这个漏洞不是“改个配置就能修好”的那种 Nacos CVE-2021-29442,这个名字在2021年中后期的Java中间件运维圈里,曾让不少团队在凌晨三点被电话叫醒。它不是那种需要你翻文档、查API、调参数的常规问题,而是一个典型的“默认行为埋雷”——…...
93、【Agent】【OpenCode】edit 工具提示词(二)
【声明】本博客所有内容均为个人业余时间创作,所述技术案例均来自公开开源项目(如Github,Apache基金会),不涉及任何企业机密或未公开技术,如有侵权请联系删除 背景 上篇 blog 【Agent】【OpenCode】edit 工…...
昇腾CANN ops-nn 交叉熵损失的融合优化:从三次 Kernel Launch 到一次
语言模型每一层的损失计算:logits → softmax → log → 取 target 位置的负值。标准做法三次 kernel launch:softmax kernel → log kernel → NLL kernel。三次 HBM 往返,中间存两个 NV 矩阵(V 是词表大小,LLaMA 是 …...
市场有效的透明化矿场安全防护系统
在矿场作业中,安全问题一直是重中之重。近年来,矿场事故时有发生,给生命和财产带来了巨大损失。据统计,过去十年间,全球矿场事故造成的直接经济损失高达数千亿美元,伤亡人数更是数以万计。因此,…...
Kubernetes事件驱动架构实践:构建响应式微服务系统
Kubernetes事件驱动架构实践:构建响应式微服务系统 一、事件驱动架构概述 事件驱动架构是一种基于事件发布/订阅模式的分布式系统设计方法。在Kubernetes中实现事件驱动架构可以实现松耦合、高可扩展的微服务系统。 1.1 事件驱动模式 模式说明适用场景发布/订阅…...
