「数据结构」二叉搜索树1:实现BST

🎇个人主页:Ice_Sugar_7
🎇所属专栏:Java数据结构
🎇欢迎点赞收藏加关注哦!

实现BST

  • 🍉二叉搜索树的性质
  • 🍉实现二叉搜索树
    • 🍌插入
    • 🍌查找
    • 🍌删除
  • 🍉性能分析

🍉二叉搜索树的性质

二叉搜索树又称二叉排序树,它可以是一棵空树,也可以是有以下性质的二叉树

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

因为左节点 < 根节点 < 右节点,所以二叉搜索树中序遍历结果是升序序列

🍉实现二叉搜索树

🍌插入

插入成功返回true,插入失败返回false
(注意:如果树中已经有关键字key,那我们就不能再插入了)

    //插入一个关键字key
    public boolean insert(int key) {
        TreeNode node = new TreeNode(key);
        if(root == null) {
            root = node;
            return true;
        }
        TreeNode cur = root;
        TreeNode parent = null;  //保存cur的双亲节点
        while(cur != null) {  //cur若为空,说明找到插入位置了
            if(cur.key < key) {
                parent = cur;
                cur = cur.right;
            } else if(cur.key > key) {
                parent = cur;
                cur = cur.left;
            } else {  //树中已经有key,不能插入
                return false;
            }
        }
        //比较key和双亲节点的key,确定key要插在parent的左边还是右边
        if(key > parent.key)
            parent.right = node;
        if(key < parent.key)
            parent.left = node;
        return true;
    }

🍌查找

根据二叉搜索树的特点,key比当前节点的值小,就往左子树找;反之则往右子树找

    //查找key是否存在
    public TreeNode search(int key) {
        if(root == null)
            return null;
        TreeNode cur = root;
        while(cur != null) {
            if(cur.key < key) {
                cur = cur.right;
            } else if(cur.key > key) {
                cur = cur.left;
            } else {
                return cur;
            }
        }
            return null;  //到这里说明找不到,返回null
    }

🍌删除

这个操作比较麻烦,因为它需要处理多种情况。大方向上分为三种情况讨论:
假设根节点为root,待删除节点是cur,它的双亲节点为parent

  1. cur的左节点为空
    ①cur就是根节点(此时parent不存在),只需让root = root.right
    ②cur不是根节点,是parent的左节点
    ③cur不是根节点,是parent的右节点
    ②和③的分析如下图:
    在这里插入图片描述

  2. cur的右节点为空
    这个和1的分析思路是一样的,就不多赘述了

  3. cur的左右节点都不为空
    使用替换法进行删除:
    就是从cur的左子树中找到最右侧的节点(这个节点是左子树中关键字最大的)max,或者从右子树中找到最左侧节点(关键字最小)min,用它的值替换掉cur的值,然后再把max或min删掉
    其实就是转化为1和2的问题,因为max和min的左节点和右节点肯定有一个为空
    在这里插入图片描述
    来看下代码实现:

    //删除key的值
    public boolean remove(int key) {
        if(root == null)
            return false;
        TreeNode cur = root;
        TreeNode parent = null;
        while(cur != null) {
            if(cur.key < key) {
                parent = cur;
                cur = cur.right;
            } else if(cur.key > key) {
                parent = cur;
                cur = cur.left;
            } else {  //找到cur了,准备把它删了
                if(cur.left == null) {
                    if(cur == root) {
                        root = root.right;
                        return true;
                    } else {
                        if(cur == parent.left)
                            parent.left = cur.right;
                        if(cur == parent.right)
                            parent.right = cur.right;
                    }
                } else if(cur.right == null) {
                    if(cur == root) {
                        root = root.left;
                        return true;
                    } else {
                        if(cur == parent.left)
                            parent.left = cur.left;
                        if(cur == parent.right)
                            parent.right = cur.left;
                    }
                } else {  //左右都不为空
                    TreeNode target = cur.right;  //让target去右子树找到最左边的节点
                    TreeNode targetParent = cur;
                    while(target.left != null) {
                        targetParent = target;
                        target = target.left;
                    }
                    //将tmp的关键字赋给cur
                    cur.key = target.key;
                    //删除tmp节点
                    if(targetParent.left == target) {
                        targetParent.left = cur.right;
                    } else {
                        targetParent.right = cur.right;
                    }
                }
                return true;
            }
        }
        return false;
    }

🍉性能分析

插入和删除等操作都必须先查找,所以查找的效率代表二叉搜索树中各个操作的性能
每次查找都要比较key和当前节点的值。
那么在最好的情况下,二叉搜索树是完全二叉树,平均比较次数是logN
而在最坏的情况下,此时二叉搜索树退化为单支树,平均比较次数就是N / 2
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FPGA开发

Quartus13.0使用 编译下载&#xff1a; 添加引脚&#xff1a; # ---------------- LED ---------------- # set_location_assignment PIN_K2 -to led_out[11] set_location_assignment PIN_J1 -to led_out[10] set_location_assignment PIN_J2 -to led_out[9] set_locatio…

SRS视频服务器使用记录

SRS是一个开源的&#xff08;MIT协议&#xff09;简单高效的实时视频服务器&#xff0c;支持RTMP、WebRTC、HLS、HTTP-FLV、SRT、MPEG-DASH和GB28181等协议。 SRS媒体服务器和FFmpeg、OBS、VLC、 WebRTC等客户端配合使用&#xff0c;提供流的接收和分发的能力&#xff0c;是一个…

Python操作MySQL基础

除了使用图形化工具以外&#xff0c;我们也可以使用编程语言来执行SQL从而操作数据库。在Python中&#xff0c;使用第三方库: pymysql来完成对MySQL数据库的操作。 安装第三方库pymysql 使用命令行,进入cmd&#xff0c;输入命令pip install pymysql. 创建到MySQL的数据库连接…

【漏洞复现】多语言药房管理系统MPMS文件上传漏洞

Nx01 产品简介 多语言药房管理系统 (MPMS) 是用 PHP 和 MySQL 开发的, 该软件的主要目的是在药房和客户之间提供一套接口&#xff0c;客户是该软件的主要用户。该软件有助于为药房业务创建一个综合数据库&#xff0c;并根据到期、产品等各种参数提供各种报告。 Nx02 漏洞描述 …

详细了解ref和reactive.

这几天看到好多文章标题都是类似于&#xff1a; 不用 ref 的 xx 个理由不用 reactive 的 xx 个理由历数 ref 的 xx 宗罪 我就很不解&#xff0c;到底是什么原因导致有这两批人&#xff1a; 抵触 ref 的人抵触 reactive 的人 看了这些文章&#xff0c;我可以总结出他们的想法…

第8章 智能租房——列表页

学习目标 掌握搜索房源列表页展示功能的逻辑&#xff0c;能够实现在列表中展示符合搜索条件的房源数据 掌握最新房源列表页展示功能的逻辑&#xff0c;能够运用分页插件以分页形式展示最新房源数据 掌握热点房源列表页展示功能的逻辑&#xff0c;能够运用分页插件以分页形式展…

Linux文本三剑客(2)

文章目录 一、Linux文本三剑客之awk使用方法awk 的原理实例一&#xff1a;只查看test.txt文件&#xff08;100行&#xff09;内第20到第30行的内容&#xff08;企业面试&#xff09;实例二&#xff1a;已知test.txt文件内容为 BEGIN 和 END 模块实例一&#xff1a;统计/etc/pas…

【单片机】简单的自定义延时程序设计(代码演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴 单片机系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过单片机的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY…

2、6作业

TCP和UDP的区别 TCP和UDP都是通信协议 TCP提供有连接的&#xff0c;稳定的&#xff0c;无误码无失真无乱序无丢失的通信 UDP提供无连接的&#xff0c;尽力的&#xff0c;可能误码可能乱序&#xff0c;可能丢失的通信 TCP每发一个数据包就需要对方回应一个应答包&#xff0c…

C++重新入门-C++判断语句

目录 1.if语句 嵌套 if 语句 2.switch语句 工作原理 语法 示例 3.三元运算符 示例 注意事项 判断结构要求程序员指定一个或多个要评估或测试的条件&#xff0c;以及条件为真时要执行的语句&#xff08;必需的&#xff09;和条件为假时要执行的语句&#xff08;可选的&…

Rust基础拾遗--核心功能

Rust基础拾遗 前言1.所有权与移动1.1 所有权 2.引用3.特型与泛型简介3.1 使用特型3.2 特型对象3.3 泛型函数与类型参数 4.实用工具特型5.闭包 前言 通过Rust程序设计-第二版笔记的形式对Rust相关重点知识进行汇总&#xff0c;读者通读此系列文章就可以轻松的把该语言基础捡起来…

推荐知识付费源码,梦想贩卖机升级版

梦想贩卖机升级版&#xff0c;变现宝吸收了资源变现类产品的许多优势&#xff0c;并剔除了那些无关紧要的元素&#xff0c;使得本产品在运营和变现能力方面实现了质的飞跃。多领域素材资源知识变现营销裂变独立版本。 演示地址&#xff1a;runruncode.com/rjcx/19689.html

电商小程序03登录页面开发

目录 1 创建应用2 创建页面3 首页功能搭建4 登录页搭建5 设置叠加效果总结 小程序开发在经过需求分析和数据源设计之后&#xff0c;就可以进入到页面开发的阶段了。首先我们需要开发登录的功能。 登录功能要求用户输入用户名和密码&#xff0c;勾选同意用户协议和隐私协议&…

第77讲用户管理功能实现

用户管理功能实现 前端&#xff1a; views/user/index.vue <template><el-card><el-row :gutter"20" class"header"><el-col :span"7"><el-input placeholder"请输入用户昵称..." clearable v-model"…

JVM-类加载器 双亲委派机制

申明&#xff1a;文章内容是本人学习极客时间课程所写&#xff0c;文字和图片基本来源于课程资料&#xff0c;在某些地方会插入一点自己的理解&#xff0c;未用于商业用途&#xff0c;侵删。 什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&a…

Peter算法小课堂—背包问题

我们已经学过好久好久的动态规划了&#xff0c;动态规划_Peter Pan was right的博客-CSDN博客 那么&#xff0c;我用一张图片来概括一下背包问题。 大家有可能比较疑惑&#xff0c;优化决策怎么优化呢&#xff1f;答案是&#xff0c;滚动数组&#xff0c;一个神秘而简单的东西…

AI:125-基于深度学习的航拍图像中地物变化检测

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带有在本地跑过的关键代码,详细讲解供…

uniapp vue3怎么调用uni-popup组件的this.$refs.message.open() ?

vue2代码 <!-- 提示信息弹窗 --><uni-popup ref"message" type"message"><uni-popup-message :type"msgType" :message"messageText" :duration"2000"></uni-popup-message></uni-popup>typ…

【集合系列】TreeMap 集合

TreeMap 集合 1. 概述2. 方法3. 遍历方式4. 排序方式5. 代码示例16. 代码示例27. 代码示例38. 注意事项9. 源码分析 其他集合类 父类 Map 集合类的遍历方式 TreeSet 集合 具体信息请查看 API 帮助文档 1. 概述 TreeMap 是 Java 中的一个集合类&#xff0c;它实现了 SortedMap…

ChatGPT高效提问—prompt常见用法(续篇九)

ChatGPT高效提问—prompt常见用法(续篇九) ​ 如何准确地向大型语言模型提出问题,使其更好地理解我们的意图,从而得到期望的答案呢?编写有效的prompt的技巧,精心设计的prompt,获得期望的的答案。 1.1 增加条件 ​ 在各种prompt技巧中,增加条件是最常用的。在prompt中…