【数据结构】关于二叉搜索树,你知道如何实现增删模拟吗???(超详解)

news2024/9/23 5:28:48

前言:

🌟🌟Hello家人们,这期讲解二叉搜索树内部实现基础功能模拟,希望能帮到屏幕前的你。

🌈上期博客在这里:http://t.csdnimg.cn/rfYFW

🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客

目录

📚️1.二叉搜索树

1.1概念:

1.2二叉树图片:

📚️2.二叉树的查找模拟

2.1思路分析

2.2画图演示 

 2.3代码实现

📚️3.二叉搜索树的插入模拟

3.1思路分析

3.2画图演示

3.3代码实现

📚️4.二叉搜索树的删除模拟

4.1思路分析

4.2画图演示

4.3代码实现 

📚️5.性能分析

📚️6.总结


📚️1.二叉搜索树

1.1概念:

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

• 若它的左子树不为空,则左子树上所有节点的值都小于根节点的值
• 若它的右子树不为空,则右子树上所有节点的值都大于根节点的值
• 它的左右子树也分别为二叉搜索树

1.2二叉树图片:

如上图,二叉搜索树的左子树都满足小于根结点的值,而右子树都满足大于根结点的值;并且在中序遍历时可以发现数据是一个由小到大排列的数据。

📚️2.二叉树的查找模拟

2.1思路分析

1.进行根结点的判断:

         如果根结点的值正好等于我们要查找的数据,那么直接返回true;

2.进行子节点的判断:

        如果子节点的值小于我们要查找的数值,那么就去结点的右边进行查找,反之就去结点          的左边进行查找

3.结束判断:

        当没有找到结点时,我们的搜索指针此时指向空结点,那么此时跳出循环,没有找到,          返回false

2.2画图演示 

 2.3代码实现

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

    }

注意:在进行操作之前要进行节点的创建,才能进行增删等操作;在查找过程中首先要进行根结点的判断,如果找到了直接返回true,返回进入一下循环查找,这里的cur要不断进行跟新,直到为空结点时才能跳出循环。

📚️3.二叉搜索树的插入模拟

3.1思路分析

1.根结点的判断:

        如果根结点为空那么直接插入,root等于插入结点

2.子节点的判断:

        如果子结点的值小于插入的数值,那么就进行右边子结点的判断,反之进行左边子节点          的判断

3.插入的结点判断:

       执行以上步骤后,超如位置,因该为叶子结点,且满足二叉搜素树的特点

3.2画图演示

 

3.3代码实现

 public void insert(int val){
        TreeNode node=new TreeNode(val);
        if(root==null){
            root=node;
            return;
        }
        TreeNode parent=null;
        TreeNode cur=root;
        while (cur!=null){
            if (cur.val<val){
                parent=cur;
                cur=cur.right;
            }else if (cur.val>val){
                parent=cur;
                cur=cur.left;
            }else {
                return;
            }
        }
        if(parent.val<val){
            parent.right= node;
        }else {
            parent.left=node;
        }
    }

注意:这里要根据结点数据,初始化结点;设置parent指针,当cur跳出循环时为空,它的父亲节点为parent,再根据parent所指数据大小进行左边插入还是右边插入;还有当插入的结点数据等于其中某个数据时,就不能进行插入操作。

📚️4.二叉搜索树的删除模拟

4.1思路分析

在删除的过程中我们要讨论如下几点情况:

设待删除结点为 cur, 待删除结点的双亲结点为 parent
1.当 cur.left == null时:
      1. cur 是 root,则 root = cur.right
      2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.right
      3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.right
2. 当cur.right == null时:
     1. cur 是 root,则 root = cur.left
     2. cur 不是 root,cur 是 parent.left,则 parent.left = cur.left

     3. cur 不是 root,cur 是 parent.right,则 parent.right = cur.left

3. 当cur.left != null && cur.right != null时:
    需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用        它 的值填补到被删除节点中,再来处理该结点的删除问题

4.2画图演示

4.3代码实现 

1.找到要删除的节点cur:

 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(parent,cur);
                return;
            }
        }
    }

   

和上述查找的过程一致,但是这里的parent始终指向cur的双亲结点,当找到要删除的节点之后执行另一个函数即可。

2.实现删除的核心代码:

private void removeNode(TreeNode parent, TreeNode cur) {
        if(cur.left == null) {
            if(cur == root) {
                root = cur.right;
            }else if(parent.left == cur) {
                parent.left = cur.right;
            }else {
                parent.right = cur.right;
            }
        }else if(cur.right == null) {
            if(cur == root) {
                root = cur.left;
            }else if(parent.left == cur) {
                parent.left = cur.left;
            }else {
                parent.right = cur.left;
            }
        }else {
            TreeNode targetParent = cur;
            TreeNode target = cur.right;
            while (target.left != null) {
                targetParent = target;
                target = target.left;
            }
            cur.val = target.val;
            if(targetParent.left == target) {
                targetParent.left = target.right;
            }else {
                targetParent.right = target.right;
            }
        }
    }

注意:这里就要根据上述思路分析进行条件判断,除了cur左右孩子是否为空的情况下,还要判断cur属于parent的那边孩子的结点,当然还有删除结点cur是否为根结点的条件判断。

在进行删除操作的时候,如果删除结点的左右树都不为空,那么此时我们要进行找到替罪羊的方法,找到左边或者右边的其中之一的替罪羊,但是由于改变节点,需要管理其子结点,所以这里的删除并不是真正意义上的删除,其实是赋值替罪羊的值过后,在对其替罪羊进行操作,这样大大减少了对删除结点的左右子树的管理 。

📚️5.性能分析

插入和删除操作都必须先查找,查找效率代表了二叉搜索树中各个操作的性能。
对有n个结点的二叉搜索树,若每个元素查找的概率相等,则二叉搜索树平均查找长度是结点在二叉搜索树的深度的函数,即结点越深,则比较次数越多。


但对于同一个关键码集合,如果各关键码插入的次序不同,可能得到不同结构的二叉搜索树:

所以查找时间复杂度

        ~~最好情况: O(logN)

        ~~最坏情况: O(N)

📚️6.总结

💬💬在本期小编讲解了,关于二叉搜索树的概念,以及增删查的重要功能模拟,以及二叉搜索树的性能分析。

关于二叉搜索树来说,模拟情况有助于我们更加深入了解其功能方法的内部实现原理~~~

🌅🌅🌅~~~~最后希望与诸君共勉,共同进步!!!


                                 💪💪💪以上就是本期内容了, 感兴趣的话,就关注小编吧。

                                                         😊😊  期待你的关注~~~

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

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

相关文章

从需求到交付:动态敏捷如何确保每一行代码都物超所值

动态敏捷方法论在软件开发中的应用 在当今快速变化的商业环境中&#xff0c;软件开发团队面临着不断变化的需求和市场挑战。传统的瀑布式开发模型已无法满足现代软件开发的灵活性和响应速度需求。动态敏捷&#xff08;Dynamic Agility&#xff09;作为一种新兴的开发方法论&…

introsort的快排跑排序OJ代码

introsort的快排跑排序OJ代码 introsort是introspective sort采⽤了缩写&#xff0c;他的名字其实表达了他的实现思路&#xff0c;他的思路就是进⾏⾃ 我侦测和反省&#xff0c;快排递归深度太深&#xff08;sgi stl中使⽤的是深度为2倍排序元素数量的对数值&#xff09;那就说…

《黑神话:悟空》在未来市场的应用与代码案例分析

作者主页: 知孤云出岫 目录 作者主页:**《黑神话&#xff1a;悟空》在未来市场的应用与代码案例分析****一、引言****二、市场应用场景分析****1. 数据驱动的市场决策****2. 游戏内经济系统的智能优化****3. 个性化推荐系统与用户体验提升** **三、市场推广与用户扩展策略***…

十一:C语言-操作符详解

1.了解二进制 其实二进制&#xff1b;八进制&#xff1b;十进制和十六进制都是数值的不同表示形式而已 二进制&#xff1a;基数为2&#xff0c;由0和1两个数字组成&#xff0c;逢2进1。八进制&#xff1a;基数为8&#xff0c;由0~7八个数字组成&#xff0c;逢8进1。十进制&am…

猫头虎 分享:Python库 SymPy 的简介、安装、用法详解入门教程 ‍

猫头虎 分享&#xff1a;Python库 SymPy 的简介、安装、用法详解入门教程 &#x1f431;‍&#x1f464; 今天猫头虎带您 深入了解 Python库 SymPy&#xff0c;这是一个强大且广泛应用于符号数学计算的库。最近有粉丝问猫哥&#xff1a;如何利用 SymPy 进行数学公式的符号化处…

【Maps JavaScript API】基础地图的创建与实现详解

文章目录 一、概述1. Google Maps JavaScript API 简介2. Simple Map 示例概述 二、创建一个基础地图1. 引入 Google Maps JavaScript API2. 初始化地图(1) 定义地图的 HTML 容器(2) 编写 JavaScript 代码初始化地图 3. 将地图集成到网页中 三、代码分析与关键点1. 地图中心点的…

32 增加系统调用(1)

系统调用在 数据手册中的描述 这是在 GDT 中的描述符 这个系统调用 segment selector 指向的时 内核的代码段。因为系统调用需要的权限比较高。 offset 指的时 在内核代码中的具体的函数的地址。

SQL Server 查询语句中,对索引列做CONVERT的影响

通常&#xff0c;在做SQL Server查询语句优化的时候&#xff0c;如果发现语句对索引列做了函数计算&#xff0c;都会建议改写&#xff0c;将计算的逻辑转移到筛选条件列上。但这种对索引列的计算&#xff0c;有时却会带来一些额外的好处。请看以下的例子&#xff1a; --测试数…

【Linux开发板pip安装库时报错解决】Error 28:No space left on device报错需要更换库的安装路径

之前在Linux开发板上尝试运行pytorch框架&#xff0c;但是需要安装torch和torchvision的库&#xff0c;很奇怪的是我按照之前pip3 install torch -i http://pypi.douban.com/simple --trusted-host pypi.douban.com的安装方式却出现了以下的报错&#xff1a; 系统报错提示说No …

R 语言学习教程,从入门到精通,R 绘图饼图(23)

1、R 绘图 条形图 条形图&#xff0c;也称为柱状图条形图&#xff0c;是一种以长方形的长度为变量的统计图表。 条形图可以是水平或垂直的&#xff0c;每个长方形可以有不同的颜色。 R 语言使用 barplot() 函数来创建条形图&#xff0c;格式如下&#xff1a; barplot(H,xlab,…

FastAPI+React18开发通用后台管理系统用户功能实战

最近开发了一个React18的后台管理系统&#xff0c;登录界面如下&#xff1a; 如果登录成功了则提示并跳转到首页&#xff1a; 点击注销按钮则提示退出系统成功&#xff1a; 没有登录就访问首页则提示请先登录。 这些功能是怎么实现的呢&#xff1f; 先看看登录功能使用…

JNA实践之Java模拟C结构体、结构体指针、结构体数组

目录 1 JNA模拟C结构体1.1 结构体本身作参数1.2 结构体指针作参数1.3 结构体内部嵌套结构体(结构体本身作参数)1.4 结构体指针作参数 2 结构体中嵌套结构体数组2.1 用作输入2.2 用作输出 3 结构体数组作参数典型错误1--内存不连续典型错误2--误用ByValue 4 Java映射C中char[]类…

scrapy--json结构数据-存储

免责声明:本文仅做演示与分享... 目录 基于命令存储的解析方法: settings.py blibli.py 基于管道存储的解析方法: 1-在爬虫文件中进行数据解析 2-在items.py定义相关属性 3-在 爬虫文件中 把 解析的数据存储封装到item类型对象中 4-把item类型对象提交给管道 5-在管道文件中…

软件设计之MySQL(6)

软件设计之MySQL(6) 此篇应在JavaSE之后进行学习: 路线图推荐&#xff1a; 【Java学习路线-极速版】【Java架构师技术图谱】 Navicat可以在软件管家下载 使用navicat连接mysql数据库创建数据库、表、转储sql文件&#xff0c;导入sql数据 MySQL数据库入门到大牛&#xff0c;my…

【吊打面试官系列-Memcached面试题】memcached 能接受的 key 的最大长度是多少?

大家好&#xff0c;我是锋哥。今天分享关于 【memcached 能接受的 key 的最大长度是多少&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; memcached 能接受的 key 的最大长度是多少&#xff1f; key 的最大长度是 250 个字符。需要注意的是&#xff0c;250 是 m…

KEIL中分散加载文件基础知识

一、分散加载文件基本概念 1、分散加载文件&#xff1a;&#xff08;即scatter file 后缀为.scf&#xff09;是一个文本文件&#xff0c;通过编写一个分散加载文件来指定ARM连接器在生成映像文件时如何分配RO,RW,ZI等数据的存放地址。如果不用分散加载文件指定&#xff0c;那么…

区域形态学demo发布

demo实现了halcon中threshold、connection、fill_up、union、difference、intersection、dilation、erosion、opening、closing等算子功能&#xff0c;区域使用行程编码表示。目前可选择的结构元有圆形、矩形、十字&#xff08;实际接口没有限制&#xff09;&#xff0c;所有结…

Flutter-->Widget上屏之路

本文主要介绍Flutter中创建一个Widget到屏幕上渲染出Widget内容的路程. 拾用本文您将获得: Widget是什么Element是什么RenderObject是什么 附加Buff: Widget直接渲染成图片文本String的绘制图片ui.Image的绘制 这一切都要从runApp方法开始说起, 如果你还不知道runApp是什么…

【非常简单】 猿人学web第一届 第12题 入门级js

这一题非常简单&#xff0c;只需要找到数据接口&#xff0c;请求参数 m生成的逻辑即可 查看数据接口 https://match.yuanrenxue.cn/api/match/12 查看请求对应的堆栈中的 requests 栈 list 为对应的请求参数 list 是由 btoa 函数传入 ‘yuanrenxue’ 对应的页码生成的 bto…

安装torchvision==0.5.0

安装pytorch 1.4 但是在当前配置的镜像源中找不到 torchvision0.5.0 这个版本的包。 直接找资源下载 网址添加链接描述 直接运行该命令&#xff0c;成功。 然后重复运行上面的命令就可以了 # CUDA 9.2 conda install pytorch1.4.0 torchvision0.5.0 cudatoolkit9.2 -c pyto…