二叉搜索树大冒险:寻找-插入-删除

news2024/11/14 20:29:52

OK,看我们题目就可知道啦,今天要分享学习的一种数据结构就是二叉搜索树。

内容题目也说了三个大概的,分别是寻找、插入、删除。

讲这个之前呢,那么就先讲讲这个二叉搜索树是何方神圣呢?

二叉搜索树:

又称二叉排序树,它或者是一颗空树,或者是具有以下性质的二叉树:

若它的左子树不为空,则左子树上的所有节点的值都小于根节点的值。

若它的右子树不为空,则右子树上的所有节点的值都大于根节点的值。

它的左右子树也分别为二叉搜索树

示例如下:

OK,讲完了这个概念,那么接下来这个操作内容吧。

首先创建这个节点先

public class SearchTree {
    class TreeNode {
        public int val;
        public TreeNode left;
        public TreeNode right;
        public TreeNode(int val){
            this.val=val;
        }
    }
     public TreeNode root=null;
}

以及把这个节点初始一个变量root,置为null。

接下来,就写这个简单的方法——查找

查找

public TreeNode 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 cur;
            }
        }
        return null;
    }

思路:

让一个cur的节点帮我去走,因为root的左边比root小,右边比root大,所以当cur.val小于key时,说明key大往右走,否则往左走,都不是,即找到了,就可以返回当前节点的值了。

插入

先上代码

public void insert(int val){
        TreeNode node=new TreeNode(val);
        if(root==null){
            root=node;
            return;
        }
        TreeNode cur=root;
        TreeNode parent=null;

        while(cur!=null){
            if(cur.val>val){
                parent=cur;
                cur=cur.left;
            }else if(cur.val<val){
                parent=cur;
                cur=cur.right;
            }else{
                return;
            }
        }
        if(parent.val>val){
            parent.left=node;
        }else{
            parent.right=node;
        }
    }

思路:

先定义好一个Node节点,保存要插入的信息,然后再定义一个parent节点来保存上一个节点的信息,为什么呢?

因为这个总体思路就是要插入的节点的值比这个当前root节点的值进行比大小,大于root就往右走,小于往左走。

接着,再定义一个cur的节点,让它去走,当cur往左还是往右走时,parent都要走到当前cur的位置

当然,插入一个已有的值,可以选择return了,

当while循环走完,意味着走到了对的位置了

举个例子

插入一个2,那么这个cur就得往左走,走到1位置才是正确的,

然后parent也是到了cur的位置。

然后,当前的parent的值和当前val的值相比,大于就插入右边,小于就插入左边,

显然这个例子中,2插入1的右边。

最后一个内容。

删除

这里的删除有些麻烦,要分三种情况

第一种情况

删除的节点左边为空

举个例子

这个当左边为空时,也有三种状况。

第一种:当root为删除的节点时,让root=cur.right

第二种:当cur为根节点的左边时,图中为3,既让root=cur.right

第三种:当cur为根节点的右边时,图中为7,既让root=cur.right

而根据这里我们也可以写出第一部分的代码了

public void remove(int key){
        TreeNode parent=null;
        TreeNode cur=root;
        while(cur!=null){
            if(cur.val<key){
                parent=cur;
                cur=cur.right;
            }else if(cur.val>key){
                parent=cur;
                cur=cur.left;
            }else{
                removeNode(parent,cur);
            }
        }
    }
 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;
             }
}

代码解释:同样的,我们删掉节点之前,也先需要找到这个节点,删除节点的事让removeNode来做。

刚刚说明的root=cur.right中的root,当然是让一个parent来记录下来(即cur前面节点的信息)

第二种情况

即删除的节点右边为空

举个例子

同样的,这里也有三种情况

第一种:当删除的节点为根节点,所以root=cur.left

第二种:当删除的节点为root的左边,图中为3,所以root=cur.left

第三种:当删除的节点为root的右边,图中为7,所以root=cur.left

所以到这里也可以写一些代码了

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

这个代码,跟第一种情况是类似的。

第三种情况

即删除的节点左右都不为空

目录

二叉搜索树:

查找

插入

删除

第一种情况

第二种情况

第三种情况

完!


举个例子

当我们要删除的节点为cur时,即图中的60,我们采用的方法是替换法,

即其一的办法是,在cur的右边找到其最小值替换掉cur,即图中的65替换掉60。

同理也可以找到cur的左边的最大值替换掉cur,

这样做是因为可以保持整棵树为一个二叉搜索树

具体这样子做(以在cur的右子树找最小值为例)

定义两个节点,一个是target,一个是targetParent。

其中,target=cur.right

targetParent=cur

让这个target去找到其最小值,找到了,再去赋值然后更新要修改的节点

修改完成后,再像其第一种情况中的当targetParent的左边为空时,让这个targetParent的左边指向

target的右边,相当于指向一个空指针,使其不再引用这个65的节点,达到删除效果

上代码

             TreeNode target=cur.right;
             TreeNode targetParent=cur;
             while(target !=null){
                 targetParent=target;
                 target =target.left;
             }
             cur.val=target.val;
             if(target ==targetParent.left){
                 targetParent.left=target .right;
             }else{
                 targetParent.right=target .right;
             }
         }

完!

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

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

相关文章

移动端 火星坐标体系、百度坐标体系和全球坐标体系,该如何选择?

项目场景&#xff1a; 在梳理项目代码时&#xff0c;看到代码中的WGS-84&#xff0c;忽然想起有次面试问我这个问题&#xff0c;今天就好好的梳理下这个问题。 问题描述 移动端获取定位一般用什么编码&#xff1f;为什么要用这个&#xff1f; 原因分析&#xff1a; 解决方案&…

J025_斗地主游戏案例开发(简版)

一、需求描述 完成斗地主游戏的案例开发。 业务&#xff1a;总共有54张牌&#xff1b; 点数&#xff1a;3、4、5、6、7、8、9、10、J、Q、K、A、2 花色&#xff1a;黑桃、红桃、方片、梅花 大小王&#xff1a;大王、小王 点数分别要组合4种花色&#xff0c;大小王各一张。…

LeetCode --- 134双周赛

题目 3206. 交替组 I 3207. 与敌人战斗后的最大分数 3208. 交替组 II 3209. 子数组按位与值为 K 的数目 一、交替组 I & II 题目中问环形数组中交替组的长度为3的子数组个数&#xff0c;主要的问题在于它是环形的&#xff0c;我们要考虑首尾相接的情况&#xff0c;如何…

【流媒体】 通过ffmpeg硬解码拉流RTSP并播放

简介 目前RTSP拉流是网络摄像头获取图片数据常用的方法&#xff0c;但通过CPU软解码的方式不仅延时高且十分占用资源&#xff0c;本文提供了一种从网络摄像头RTSP硬解码的拉流的方法&#xff0c;并且提供python代码以便从网络摄像头获取图片进行后续算法处理。 下载ffmpeg F…

回归求助 教程分享

大侠幸会&#xff0c;在下全网同名「算法金」 0 基础转 AI 上岸&#xff0c;多个算法赛 Top 「日更万日&#xff0c;让更多人享受智能乐趣」 今日 217/10000 抱个拳&#xff0c;送个礼 更多内容&#xff0c;见微*公号往期文章&#xff1a;通透&#xff01;&#xff01;十大回…

Python | Leetcode Python题解之第233题数字1的个数

题目&#xff1a; 题解&#xff1a; class Solution:def countDigitOne(self, n: int) -> int:# mulk 表示 10^k# 在下面的代码中&#xff0c;可以发现 k 并没有被直接使用到&#xff08;都是使用 10^k&#xff09;# 但为了让代码看起来更加直观&#xff0c;这里保留了 kk,…

计算机网络——网络层(IP地址与MAC地址、地址解析协议ARP、IP数据报格式以及转发分组、ICMP、IPV6)

IP地址与MAC地址 由于MAC地址已固化在网卡上的ROM 中&#xff0c;因此常常将 MAC地址称为硬件地址或物理地址&#xff1b;物理地址的反义词就是虚拟地址、软件地址或逻辑地址&#xff0c;IP地址就属于这类地址。 从层次的角度看&#xff0c;MAC地址是数据链路层使用的地址&…

基于lstm的股票Volume预测

LSTM&#xff08;Long Short-Term Memory&#xff09;神经网络模型是一种特殊的循环神经网络&#xff08;RNN&#xff09;&#xff0c;它在处理长期依赖关系方面表现出色&#xff0c;尤其适用于时间序列预测、自然语言处理&#xff08;NLP&#xff09;和语音识别等领域。以下是…

特殊记忆柱群、特殊感觉中枢、强度中枢

智能软件的某些思维状态的标志&#xff0c;能够被一般感觉中枢“先天”感知&#xff0c;或者是与一般感觉中枢“后天”建立记忆联系。在它们建立奖惩记忆联系后&#xff0c;这些思维状态能够兴奋特殊感觉中枢或者一般感觉中枢对应的记忆柱群&#xff0c;也能够被相应感觉中枢的…

【大模型书籍】复旦新出!大规模语言模型:从理论到实践(推荐)

自2018年以来&#xff0c;包含Google、OpenAI、Meta、百度、华为等公司和研究机构都纷纷发布了包括BERT&#xff0c; GPT等在内多种模型&#xff0c;并在几乎所有自然语言处理任务中都表现出色。 今天给大家推荐一本大模型方面的书籍<大规模语言模型&#xff1a;从理论到实…

【数学建模】——力学模型建立的基本理论及方法

目录 一、基本理论 1. 牛顿力学 1.1 牛顿第一定律&#xff08;惯性定律&#xff09; 1.2 牛顿第二定律&#xff08;动力学定律&#xff09; 1.3 牛顿第三定律&#xff08;作用反作用定律&#xff09; 2. 能量守恒定律 2.1 动能和势能 2.2 能量守恒 3. 动量守恒定律…

简易秒表的实现

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 参考代码 描述 请编写一个模块&#xff0c;实现简易秒表的功能&#xff1a;具有两个输出&#xff0c;当输出端口second从1-60循环计数&#xff0c;每当second计数到60&#xff0c;输出端口minute加一&#xff0c;一直…

java配置nginx网络安全,防止国外ip访问,自动添加黑名单,需手动重新加载nginx

通过访问日志自动添加国外ip黑名单 创建一个类&#xff0c;自己添加一个main启动类即可测试 import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.json.JSONArray; import org.json.JSONObject; import org.sp…

Azcopy Sync同步Azure文件共享

Azcopy Sync同步Azure文件共享 一、工作原理二、安装 AzCopy在 Windows 上在 Linux 上 三、资源准备1. 创建源和目标 Azure 存储账户2. 创建源和目标文件共享3. 确定路径4. 生成源和目的存储账户的共享访问签名&#xff08;SAS&#xff09;令牌配置权限示例生成的 URL 四、Azco…

Java小白入门到实战应用教程-开发环境搭建-IDEA2024安装激huo详细教程

writer:eleven 安装IDEA2024 一、下载IDEA 推荐大家去官网下载 我这里也给大家直接准备了安装包&#xff0c;和激huo教程&#xff0c;大家可以自行下载使用。 注意&#xff1a;激huo教程只用于学习交流&#xff0c;不可商用。 IDEA2024安装包及激huo教程 说明&#xff1a…

prompt第二讲-langchain实现中英翻译助手

文章目录 prompt模板 (prompt template)langchain 中的prompt模板 (prompt template)langchain实现中英翻译助手 prompt模板 (prompt template) 开篇我介绍了在llm中&#xff0c;通常输入的那个字符串会被我们称之为prompt&#xff0c;下面就是一个中英文翻译助手的prompt例子…

使用F1C200S从零制作掌机之USB从机

OTG做从机&#xff0c;实现使用RNIDS功能访问网络&#xff0c;实现模拟成U盘PC可访问。 最后实现OTG的软件主从切换。 一、RNDIS 设备树的otg模式先设置为&#xff1a;peripheral &usb_otg {dr_mode "peripheral"; /* otg host peripheral */status "…

基于springboot+vue+uniapp的超市购物系统小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…

Android Studio启动报错:The emulator process for AVD Pixel_5_API_30 has terminated

Android Studio启动AVD报错&#xff1a; The emulator process for AVD Pixel_5_API_30 has terminated. 原因&#xff1a;安装时使用自定义安装后&#xff0c;修改了默认安装目录。 而avd文件默认在 C:\Users\用户名\.android 目录下。所以导致打开AVD时报错。 解决方法&am…

WIFI连接阿里云

目录 1 实现功能 2 器件 3 AT指令 4 阿里云配置 4.1 打开阿里云 4.2 创建产品 4.3 添加设备 5 STM32配置 5.1 基础参数 5.2 功能定义 6 STM32代码 本文主要是记述一下&#xff0c;如何使用阿里云物联网平台&#xff0c;创建一个简单的远程控制小灯示例。 1 实现功能…