【Java数据结构】——二叉搜索树

目录

🎈概念

🎈操作-查找

🎈操作-插入

🎈操作-删除(难点)


🎈概念

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

二叉搜索树  左<根<右

{5,3,4,1,7,8,2,6,0,9} 如何创建成上面的二叉搜索树,使每个子树的左孩子<根<右孩子(前提是左孩子和右孩子都不为空的情况下)

🎈操作-查找

我们根据上述的红色文字进行搜索查找。

 public boolean search(int key) {TreeNode cur = root;while (cur != null) {//如果值小于关键字,那么去二叉树的右边if (cur.val < key) {cur = cur.right;//如果值大于关键字,那么去二叉树的左边} else if (cur.val > key) {cur = cur.left;} else {return true;}}return false;}

🎈操作-插入

思路:如果这个树是空树,我们就直接插入

           如果这个树不是空树,按照查找的逻辑进行插入位置,插入新结点。

  • 如果根节点==val 返回false 
  • 如果根节点< val  去cur左子树查找
  • 如果根节点>val   去cur右子树查找

cur==null的时候,我们就要插入该节点(但是我们发现,如果遇到cur==null的时候,cur到了空的地方去,那谁记录cur的父节点呢?怎么给节点给cur所在位置呢?

我来用图给你们展示一下

此时我们通过cur=cur.left ,cur到了null的位置,然后我们要进行,插入值,该如何插入呢,此时我们就得给cur的父节点也记录下来,然后让node=parent.left。


    /*** 插入** @param val* @return true 表示插入成功, false 表示插入失败*/public boolean insert(int val) {//如果是空树,那么就将val直接给根if (root == null) {root = new TreeNode(val);return true;}TreeNode cur = root;TreeNode parent = null;while (cur != null) {if (val < cur.val) {parent = cur;cur = cur.left;} else if (val > cur.val) {parent = cur;cur = cur.right;} else {return false;}}//上面并没有将新的节点插入进去//我们看到上面不管是cur.right还是cur.left赋值给cur后,cur=null,此时的值并没有插入进行,而是判空结束了TreeNode node = new TreeNode(val);if (parent.val > val) {//插入到左边parent.left = node;} else {parent.right = node;}//我们看到parent的作用其实就是当cur==null的时候//我们需要插入return true;}

🎈操作-删除(难点)

设待删除结点为 cur, 待删除结点的双亲结点为 parent

1. cur.left == null
  • 1. cur root,则 root = cur.right
  • 2. cur 不是 rootcur parent.left,则 parent.left = cur.right
  • 3. cur 不是 rootcur parent.right,则 parent.right = cur.right
如果cur的左边空
cur在parent的左边,但是cur的左边空,那么我们将cur的右边节点给parent的左边
cur在parent的右边,但是cur的左边空,那么我们将cur的右边节点给parent的右边
(cur在parent的哪一边,就将cur左右哪一个不为空的节点给parent的哪一边)
2. cur.right == null
  • 1. cur root,则 root = cur.left
  • 2. cur 不是 rootcur parent.left,则 parent.left = cur.left
  • 3. cur 不是 rootcur parent.right,则 parent.right = cur.left

cur左边为空,那么就将cur的左边节点 要么给parent的左边,那么parent的右边 //(取决于 cur在parent的哪一边)

3. cur.left != null && cur.right != null
  • 1. 需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题
要么在左树中找到最大值(左数最右边的值),要么在右数找到最小值(右数最左边值)我们最终的目的是让cur的右节点给cur,然后让cur指向cur的右树的最大值。

这种情况下我们就要将,6给cur,然后让原先6对应的值置空。


用tp记录cur的位置,然后t是tp的右孩子,为什么选择右孩子呢?因为我们要删除cur对应的值,那么我们就有俩种选择  (要么cur左边的最大值,要么cur右边的最小值)

此时我选择是找cur右边的最小值进行。

t是cur的右边,然后我们要先判断一下 是否t的左边为不为空,如果不为空,那么我们就要进入左边,因为二叉搜索树的特点就是 左孩子<根节点<右孩子,所以我们当初就是要找到cur的右边的最小值,就是一直往cur右孩子的左边找,不为空,那么我们就要将6赋值给cur,然后让置空即可。

如果下面还有值,如果右节点有值,那么就将那个右值赋值,如果左节点有值,那么就将左值赋值。


    public void remove(int key){//移除之前我们需要找到这个keyTreeNode cur = root;TreeNode parent=cur;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);}}}public void removeNode(TreeNode cur,TreeNode parent){if(cur.left==null){//左树空if(cur==root){root=cur.right;} else if (cur==parent.left) {parent.left=cur.right;}else{parent.right=cur.right;}//如果cur的左边空//cur在parent的左边,但是cur的左边空,那么我们将cur的右边节点给parent的左边//cur在parent的右边,但是cur的左边空,那么我们将cur的右边节点给parent的右边//(cur在parent的哪一边,就将cur左右哪一个不为空的节点给parent的哪一边)} 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;}//cur左边为空,那么就将cur的左边节点 要么给parent的左边,那么parent的右边//(取决于 cur在parent的哪一边)} else {//要么在左树中找到最大值(左数最右边的值)//要么在右数找到最小值(右数最左边值)//cur俩边都不为空TreeNode tp=cur;TreeNode t=cur.right;//此时的cur'是关键字,cur的左右俩边都不为空,我们要将cur的右边值给到cur// (cur右节点的左节点不为空,我们就将if(t.left!=null){tp=t;t=t.left;}cur.val=t.val;//删除t//如果t在tp左边,将t的右边值给tp左边//如果t在tp右边,将t的右边值给tp的右边if(tp.left==t){tp.left=t.right;}else{tp.right=t.right;}}}

今天张老师生病了。

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

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

相关文章

编码器原理图

操作 旋转编码器提供两种交互方式&#xff1a; 每次用户旋转旋钮时&#xff0c;都会在 DT 和 CLK 引脚上产生低电平信号&#xff1a; 顺时针旋转会先使CLK引脚变为低电平&#xff0c;然后DT引脚也变为低电平。 逆时针旋转会使 DT 引脚首先变为低电平&#xff0c;然后 CLK 引脚…

力扣● 1049. 最后一块石头的重量 II ● 494. 目标和 ● 474.一和零

● 1049. 最后一块石头的重量 II 题目要把石头分成两堆&#xff0c;这两堆的重量差值最小。相撞之后剩下的石头重量就最小。其实就是要尽量把石头分为差不多重量的两堆&#xff0c;和昨天的● 416. 分割等和子集相似&#xff0c;这样就转换成了01背包问题。 和416题一样&…

医疗行业数据分析,为医疗提质增效提供科学支持

信息化时代的到来&#xff0c;医疗行业数据分析已成为提升医疗服务质量和效率的重要手段。医院拥有大量的医疗数据&#xff0c;医疗数据中包含着很多宝贵的信息与规律&#xff0c;通过深入的数据分析&#xff0c;能够为决策者提供直观、深入的数据洞察&#xff0c;帮助医疗服务…

docker 转为docker-compose(composerize 命令)

可以使用Composerize将Docker命令转换为Docker Compose文件。 例如&#xff1a;将docker run命令转换为Docker Compose格式&#xff0c;只需用Composerize运行它&#xff0c;如下所示&#xff1a; composerize docker run -d -p 9000:9000 -v /var/run/docker.sock:/var/run/…

【Django】执行查询——查询JSONField

JSONField 本篇的例子以下面这个模型为基础&#xff1a; from django.db import modelsclass Dog(models.Model):name models.CharField(max_length200)data models.JSONField(nullTrue)def __str__(self):return self.name保存和查询None值 在使用JSONField时&#xff0c…

CI/CD笔记.Gitlab系列.`gitlab-ci.yml`中的头部关键字

CI/CD笔记.Gitlab系列 gitlab-ci.yml中的头部关键字 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.ne…

JVM(2)

JVM类加载 指的是java进程运行时,需要把.class文件从硬盘加载到内存,并进行一系列校验解析的过程. 核心: .class文件>类对象; 硬盘>内存. 类加载过程 在整个JVM的执行流程中,和程序员关系最密切的就是类加载的过程了,所以我们来看一下类加载的执行流程. 对于一个类…

MySQL NDB Cluster 分布式架构搭建 自定义启动与重启Shell脚本

此次NDB Cluster使用三台虚拟机进行搭建&#xff0c;一台作为管理节点&#xff1b;而对于另外两台服务器&#xff0c;每一台都充当着数据节点和SQL节点的角色。注意不是MGR主从复制架构&#xff0c;而是分布式MySQL架构。 创建 /var/lib/mysql-cluster/config.ini Cluster全局…

Matlab 机器人工具箱 Link类

文章目录 1 Link类1.1 机械臂Link类1.2 构造函数1.3 信息/显示方法1.4 转换方法1.5 操作方法1.6 测试方法1.7 重载操作1.8 属性(读/写)1.9 例子2 Link.Link2.1 创建机器人连杆对象2.2 OPTIONS2.3 注意2.4 旧语法2.5 例子3 Link的其他函数3.1 Link.A3.2 Link.char3.3 Link.displ…

【StarryCoding P99】三角形数字的位置 题解(动态规划+组合数学+滚动数组)

[P99] 三角形数字的位置 我们都知道著名的杨辉三角&#xff0c;长下面这个样子&#xff1a; 11 11 2 1 1 3 3 1 ...将他们从上往下可以排列为&#xff1a;1,1,1,1,2,1,1,3,3,1,... 这样一个数列。 有 q q q次询问&#xff0c;每次询问请你求出数字 N N N第一次在数列中出现的…

【python】遵守 robots.txt 规则的数据爬虫程序

程序1 编写一个遵守 robots.txt 规则的数据爬虫程序涉及到多个步骤&#xff0c;包括请求网页、解析 robots.txt 文件、扫描网页内容、存储数据以及处理异常。由于编程语言众多&#xff0c;且每种语言编写爬虫程序的方式可能有所不同&#xff0c;以下将使用 Python 语言举例&am…

MATLAB知识点:if条件判断语句的嵌套

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自​第4章&#xff1a;MATLAB程序流程控制 我们通过一个…