Java数据结构-二叉搜索树

目录

  • 1. 概念
  • 2. 二叉搜索树的操作
    • 2.1 查找
    • 2.2 插入
    • 2.3 删除
  • 3. 全部代码

1. 概念

二叉搜索树是特殊的二叉树,也叫二叉排序树,它的特点是:每个结点的左子树上的所有结点的值都小于这个结点的值,右子树上的所有结点的值都大于这个结点的值,另外所有的左子树和右子树也分别为二叉搜索树,如图:
在这里插入图片描述

2. 二叉搜索树的操作

2.1 查找

根据二叉搜索树的性质来,很容易可以理解查找的逻辑:从根结点开始,比较结点的值与待查找的值,如果待查找的值比根结点的值小,说明待查找的结点一定在树的左边,如图
在这里插入图片描述
当然也有其他情况:根结点为空、该树不存在要查找的这个结点,这个时候直接返回null就可以了

public TreeNode search(int key) {TreeNode cur = root;while (cur != null) {if (cur.val > key) {cur = cur.left;} else if (cur.val < key) {cur = cur.right;} else {return cur;}}return null;
}

2.2 插入

插入的前提:插入一定是在叶子结点上插入,因为插入之后也要满足二叉搜索树的性质,插入之前需要查找要插入的位置,而查找的逻辑和刚才的逻辑一样
在这里插入图片描述

2.3 删除

删除的情况比较复杂,主要分为以下情况(假设del为要删除的结点,parent为del的父亲结点):

1、cur.left == null

  • 1、del 是root
  • 2、del 不是root,del是parent.left
  • 3、del 不是root,del是parent.right

2、cur.right == null

  • 1、del 是root
  • 2、del 不是root,del是parent.left
  • 3、del 不是root,del是parent.right

3、cur.left != null && cur.right != null

下面我们一个一个分析
情况1:del.left==null

  • 情况1.1:del是根结点root,删除逻辑:root =del.right
    在这里插入图片描述

  • 情况1.2 :del不是根结点,del是parent.left删除逻辑:parent.left=del.right
    在这里插入图片描述

  • 情况1.3:del不是根结点,del是parent.right,删除逻辑:parent.right=del.right
    在这里插入图片描述
    情况2:del.right==null

  • 情况2.1:del是根结点root,删除逻辑root = del.left
    在这里插入图片描述

  • 情况2.2:del不是根结点,del是parent.left,删除逻辑:parent.left = del.left
    在这里插入图片描述

  • 情况2.3:del不是根结点,del是parent.right,删除逻辑:parent.right = del.left
    在这里插入图片描述
    情况3:要删除的结点左右都不为空
    如图
    在这里插入图片描述

两种方法:
1.找到del的左树找值最大的结点,将del结点的值替换成这个值,接着删除这个最大值的结点,如上图的37,删除之后的情况如下
在这里插入图片描述

2.找到del的右子树找值最小的结点,将del结点的值替换成这个值,接着删除这个最小值的结点,如上图的45,删除之后的结果如下
在这里插入图片描述

3. 全部代码

public class BinarySearchTree {static class TreeNode {int val;TreeNode left;TreeNode right;public TreeNode(int val) {this.val = val;}}public TreeNode root;/*** 查找** @return*/public TreeNode find(int key) {TreeNode cur = root;while (cur != null) {if (cur.val > key) {cur = cur.left;} else if (cur.val < key) {cur = cur.right;} else {return cur;}}return null;}//插入public void insert(int key) {TreeNode cur = root;TreeNode parent = null;TreeNode newNode = new TreeNode(key);if (cur == null) {root = newNode;return;}while (cur != null) {if (cur.val > key) {parent = cur;cur = cur.left;} else if (cur.val < key) {parent = cur;cur = cur.right;} else {return;}}if (parent.val > key) {parent.left = newNode;} else {parent.right = newNode;}}//删除public void delete(int key) {TreeNode cur = root;TreeNode parent = null;while (cur != null) {if (key > cur.val) {parent = cur;cur = cur.right;} else if (key < cur.val) {parent = cur;cur = cur.left;} else {//删除结点remove(parent, cur);return;}}}// 分情况讨论private void remove(TreeNode parent, TreeNode del) {//情况1:del.left==nullif (del.left == null) {//情况1.1 del是rootif (del == root) {root = del.right;} else {if (del == parent.left) {//情况1.2 del不是root,del是parent.leftparent.left = del.right;} else if (del == parent.right) {//情况1.3 del不是root,del是parent.rightparent.right = del.right;}}} else if (del.right == null) {//情况2:del.right==nullif (del == root) {//情况2.1 del是rootroot = del.left;} else {if (del == parent.left) {//情况2.2 del是parent.leftparent.left = del.left;} else if (del == parent.right) {//情况2.3 del是parent.rightparent.right = del.left;}}} else {//情况3 del.left和del.right都不为空//将del右树的值最小的结点或者左树的值最大的结点和del替换//右边找TreeNode target = del.right;TreeNode targetP = del;while (target.left != null) {targetP = target;target = target.left;}//删除之前先交换del.val = target.val;//分情况删除if (target == targetP.right) {targetP.right = target.right;}if (target == targetP.left) {targetP.left = target.right;}}}
}

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

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

相关文章

详解 Spark 编程之 RDD 依赖关系

一、依赖与血缘关系 依赖&#xff1a;两个相邻 RDD 之间的关系血缘关系&#xff1a;多个连续的 RDD 的依赖由于 RDD 不会保存数据&#xff0c;为了提高容错性&#xff0c;每个 RDD 都会保存自己的血缘关系&#xff0c;一旦某个转换过程出现错误&#xff0c;可以根据血缘关系重新…

随身wifi网络卡顿怎么解决?随身WiFi哪个牌子的最好用?排名第一名的随身WiFi!

对于随身wifi靠不靠谱这个问题&#xff0c;网上一直存在争议。很多人的随身wifi网速不稳定&#xff0c;信号看着满格就是上不了网。关于随身wifi卡顿到底该怎么解决呢&#xff1f; 1.如果是设备网络在一个地方上网速度很快&#xff0c;换一个地方网络就不行了&#xff0c;很可能…

Linux学习笔记(清晰且清爽)

本文首次发布于个人博客 想要获得最佳的阅读体验&#xff08;无广告且清爽&#xff09;&#xff0c;请访问本篇笔记 Linux安装 关于安装这里就不过多介绍了&#xff0c;安装版本是CentOS 7&#xff0c;详情安装步骤见下述博客在VMware中安装CentOS7&#xff08;超详细的图文教…

ios v品会 api-sign算法

vip品会 api-sign算法还原 ios入门案例 视频系列 IOS逆向合集-前言哔哩哔哩bilibili 一、ios难度与安卓对比 这里直接复制 杨如画大佬的文章的内容&#xff1a; ios难度与安卓对比 很多人说ios逆向比安卓简单&#xff0c;有以下几个原因 1 首先就是闭源&#xff0c;安卓开源…

vscode过滤器@modified(查看配置了哪些设置)

文档 visualstudio•docs•getstarted•settingshttps://code.visualstudio.com/docs/getstarted/settings 说明 使用modified可以过滤出&#xff1a; 配置过的设置&#xff08;和默认值不同&#xff09;&#xff1b; 在 settings.json 文件中配置了值的设置 步骤 1.打开…

Vue3实战笔记(53)—奇怪+1,VUE3实战模拟股票大盘工作台

文章目录 前言一、实战模拟股票大盘工作台二、使用步骤总结 前言 实战模拟股票大盘工作台 一、实战模拟股票大盘工作台 接上文&#xff0c;这两天封装好的组件直接应用,上源码&#xff1a; <template><div class"smart_house pb-5"><v-row ><…

JS对象由浅入深

对象 对象&#xff08;Object&#xff09;&#xff1a;JavaScript里的一种数据类型&#xff08;引用类型&#xff09;&#xff0c;也是用于存储数据的 好处&#xff1a;可以用来详细的描述某个事物&#xff0c;是用键值对形式存储语义更明了 特点&#xff1a;对象数据是无序的&…

模型 FABE(特性 优势 好处 证据)法则

说明&#xff1a;系列文章 分享 模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。特性、优势、好处、证据&#xff0c;一气呵成。 1 FABE法则的应用 1.1 FABE法则营销商用跑步机 一家高端健身器材公司的销售代表正在向一家新开的健身房推销他们的商用跑步机。以下…

【数据分享】中国电力年鉴(2004-2022)

大家好&#xff01;今天我要向大家介绍一份重要的中国电力统计数据资源——《中国电力年鉴》。这份年鉴涵盖了从2004年到2022年中国电力统计全面数据&#xff0c;并提供限时免费下载。&#xff08;无需分享朋友圈即可获取&#xff09; 数据介绍 自1993年首次出版以来&#xf…

【数据结构】链表与顺序表的比较

不同点&#xff1a; 顺序表和链表是两种常见的数据结构&#xff0c;他们的不同点在于存储方式和插入、删除操作、随机访问、cpu缓存利用率等方面。 一、存储方式不同: 顺序表&#xff1a; 顺序表的存储方式是顺序存储&#xff0c;在内存中申请一块连续的空间&#xff0c;通…

Java运算符及程序逻辑控制

&#x1f389;welcome to my blog 请留下你宝贵的足迹吧(点赞&#x1f44d;评论&#x1f4dd;收藏⭐&#xff09; &#x1f493;期待你的一键三连&#xff0c;你的鼓励是我创作的动力之源&#x1f493; &#x1f423;目录 &#x1f340;运算符&#x1f4da;1.算术运算符&#x…

python判断文件是否存在

import os test_path "/Users/yxk/Desktop/test/GrayScale.tif" if(os.path.exists(test_path)):print(文件存在&#xff01;&#xff01;&#xff01;&#xff01;) else:print("文件不存在&#xff01;&#xff01;&#xff01;&#xff01;")结果如下 …

RabbitMQ(四)事务消息,惰性队列,优先队列

文章目录 事务消息概念配置 惰性队列概念应用场景 优先队列概念配置 事务消息 仅在生产者端有效&#xff0c;消费端无效 概念 总结&#xff1a; 在生产者端使用事务消息和消费端没有关系在生产者端使用事务消息仅仅是控制事务内的消息是否发送提交事务就把事务内所有消息都发送…

Java面试——专业技能

优质博文&#xff1a;IT-BLOG-CN 一、简单讲下 Java 的跨平台原理 由于各个操作系统&#xff08;Windows&#xff0c;Linux等&#xff09;支持的指令集不是完全一致的。就会让我们程序在不同的操作系统上要执行不同的程序代码。Java 开发了适用于不同操作系统及位数的 Java 虚拟…

【教程】自监督 对比学习,代码,爽学一波

from&#xff1a; https://docs.lightly.ai/self-supervised-learning/examples/simclr.html

代码随想录第22天|回溯part2 组合总和III电话号码的字母组合

216.组合总和III 当组合的数量为k就判断和&#xff0c;并且返回。 在枚举的时候可以进行剪枝&#xff0c;如果总和已经超过了n&#xff0c;那么就没必要继续递归下去了 class Solution { public:vector<int> path;vector<vector<int>> res;void backTrackin…

Java版本家政上门系统源码,自主研发、安全可控,支持任意二次开发

家政上门系统源码&#xff0c;Java版本&#xff0c;自主研发、安全可控。支持任意二次开发、有丰富合作案例。多端管理&#xff1a;管理端、用户端、服务端。 技术参数&#xff1a; 技术架构&#xff1a;springboot、mysql 、Thymeleaf 开发语言&#xff1a;java1.8、vue 开…

软件开发步骤详解

一、引言 随着信息技术的迅猛发展&#xff0c;软件已成为现代社会不可或缺的一部分。无论是企业运营、个人生活还是科学研究&#xff0c;都离不开各种软件的支持。因此&#xff0c;掌握软件开发的步骤和技巧对于IT从业者来说至关重要。本文旨在详细介绍软件开发的整个流程&…

计算机网络期末复习(1)计算机网络在信息时代对的作用 计算机网络的定义和分类 三种交换方法

计算机网络在信息时代扮演着至关重要的角色&#xff0c;它极大地改变了我们生活、工作和学习的方式。 计算机网络在信息时代的作用 信息共享与传播&#xff1a;计算机网络使全球范围内的信息快速共享成为可能&#xff0c;无论是新闻、学术研究还是娱乐内容&#xff0c;都可以…

初识 JavaScript

目录 1. 什么是 JavaScript2. JS 引入方式2.1 内部引入方式2.2 外部引入方式 3. JS 中的注释4. JS 中的结束符5. 输入和输出5.1 输出5.2 输入 6. 变量与常量6.1 变量的声明6.2 变量的赋值6.3 常量 7. JS 中的数据类型8. JS 中的类型转换8.1 隐式转换8.2 显式转换 正文开始 1. …