MapSet之二叉搜索树

系列文章:

                 1.   先导片--Map&Set之二叉搜索树

                 2.   Map&Set之相关概念

目录

前言

1.二叉搜索树

1.1 定义

1.2 操作-查找

1.3 操作-新增

1.4 操作-删除(难点)

1.5 总体实现代码

1.6 性能分析


前言

      TreeMap 和 TreeSet 是 Java 中基于搜索树实现的 Map 和 Set。实际上,它们使用的是红黑树数据结构,而红黑树是一种近似平衡的二叉搜索树。在红黑树的基础上,还添加了颜色属性以及红黑树性质验证来确保树的平衡性,所以我们需要了解一下二叉搜索树这个概念。

1.二叉搜索树

1.1 定义

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

1.2 操作-查找

如果根节点不为空:

如果根节点key == 查看key 返回true

如果根节点key > 查看key 在其左子树查找

如果根节点key < 查看key 在其右子树查找

否则返回false

实现代码:

class BinarySearchTree {public static class Node {int key;Node left;Node right;public Node(int key) {this.key = key;}}private Node root = null;/*** 搜索* @param key* @return*/public Node search(int key) {Node cur = root;while (cur != null){if(cur.key == key){return cur;}else if (key < cur.key){cur = cur.left;}else{cur = cur.right;}}return null;}
}

1.3 操作-新增

1.如果树为空树,即根 == null,直接插入

2.如果树不是空树,按照查找逻辑查找位置,插入新结点

实现代码:

class BinarySearchTree {public static class Node {int key;Node left;Node right;public Node(int key) {this.key = key;}}private Node root = null;/*** 插入** @param key* @return*/public boolean insert(int key) {Node cur = root;if (cur == null) {cur = new Node(key);return true;}Node parent = null;while (cur != null) {if (key == cur.key) {return false;} else if (key < cur.key) {parent = cur;cur = cur.left;} else {parent = cur;cur = cur.right;}}Node node = new Node(key);if (key < parent.key) {parent.right = node;} else {parent.left = node;}return true;}
}

1.4 操作-删除(难点)

设待删除结点为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;

需要使用替换法进行删除,即在它的右子树中寻找中序下的第一个结点(关键码最小),用它的值填补到被删除节点中,再来处理该结点的删除问题。

实现代码:

class BinarySearchTree {public static class Node {int key;Node left;Node right;public Node(int key) {this.key = key;}}private Node root = null;/*** 删除** @param key* @return*/public boolean delete(int key) {Node cur = root;Node parent = null;while (cur != null) {if (key == cur.key) {deleteValue(cur, parent);return true;} else if (key < cur.key) {parent = cur;cur = cur.left;} else {parent = cur;cur = cur.right;}}return false;}public void deleteValue(Node cur, Node parent) {//cur左右孩子都不在if (cur.left == null && cur.right == null) {if (parent.right == cur) {parent.right = null;} else {parent.left = null;}//cur左孩子不在}else if (cur.left == null) {if (cur == root) {root = root.right;} else if (cur == parent.right) {parent.right = cur.right;} else {parent.left = cur.right;}//cur右孩子不在}else if (cur.right == null) {if (cur == root) {root = root.left;} else if (cur == parent.right) {parent.right = cur.left;} else {parent.left = cur.left;}//左右均在}else{//为删除节点的右节点Node target = cur.right;Node targetParent = cur;//找右树最左节点while (target.left != null){targetParent = target;target = target.left;}cur.key = target.key;if(targetParent.left == target){targetParent.left = target.right;}else{targetParent.right = target.right;}}}
}

1.5 总体实现代码

class BinarySearchTree {public static class Node {int key;Node left;Node right;public Node(int key) {this.key = key;}}private Node root = null;/*** 搜索** @param key* @return*/public Node search(int key) {Node cur = root;while (cur != null) {if (cur.key == key) {return cur;} else if (key < cur.key) {cur = cur.left;} else {cur = cur.right;}}return null;}/*** 插入** @param key* @return*/public boolean insert(int key) {Node cur = root;if (cur == null) {cur = new Node(key);return true;}Node parent = null;while (cur != null) {if (key == cur.key) {return false;} else if (key < cur.key) {parent = cur;cur = cur.left;} else {parent = cur;cur = cur.right;}}Node node = new Node(key);if (key < parent.key) {parent.right = node;} else {parent.left = node;}return true;}/*** 删除** @param key* @return*/public boolean delete(int key) {Node cur = root;Node parent = null;while (cur != null) {if (key == cur.key) {deleteValue(cur, parent);return true;} else if (key < cur.key) {parent = cur;cur = cur.left;} else {parent = cur;cur = cur.right;}}return false;}public void deleteValue(Node cur, Node parent) {//cur左右孩子都不在if (cur.left == null && cur.right == null) {if (parent.right == cur) {parent.right = null;} else {parent.left = null;}//cur左孩子不在}else if (cur.left == null) {if (cur == root) {root = root.right;} else if (cur == parent.right) {parent.right = cur.right;} else {parent.left = cur.right;}//cur右孩子不在}else if (cur.right == null) {if (cur == root) {root = root.left;} else if (cur == parent.right) {parent.right = cur.left;} else {parent.left = cur.left;}//左右均在}else{//为删除节点的右节点Node target = cur.right;Node targetParent = cur;//找右树最左节点while (target.left != null){targetParent = target;target = target.left;}cur.key = target.key;if(targetParent.left == target){targetParent.left = target.right;}else{targetParent.right = target.right;}}}
}

1.6 性能分析

      在二叉搜索树中,插入和删除操作都需要先进行查找。查找的效率直接影响了这些操作的性能。对于一个有n个节点的二叉搜索树,如果每个元素被查找的概率相等,那么平均查找长度将取决于节点在二叉搜索树中的深度。换句话说,节点越深,需要进行的比较次数就越多。

     然而,对于相同的关键码集合,如果插入关键码的顺序不同,可能会得到不同结构的二叉搜索树。这是因为二叉搜索树的性质要求左子树的所有节点的值小于根节点的值,右子树的所有节点的值大于根节点的值。因此,不同的插入顺序可能会导致树的结构有所不同,从而影响查找效率。

最优情况下,二叉搜索树为完全二叉树,其平均比较次数为:log(N)

最差情况下,二叉搜索树退化为单支树,其平均比较次数为:N/2

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

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

相关文章

DELTA_IA-ASD_ASDA-A2简明教程

该文章仅供参考&#xff0c;编写人不对任何实验设备、人员及测量结果负责&#xff01;&#xff01;&#xff01; 0 引言 文章主要介绍电机的硬件连接、软件配置、转动调试以及软件控制。文章中提到的内容在产品手册中都有说明&#xff0c;强烈建议在操作前通读产品手册&#…

RocketMQ高级特性三-消费者分类

目录 前言 概述 区别 PullConsumer 定义与概述 原理机制 使用场景 优缺点 Java 代码示例 SimpleConsumer 定义与概述 原理机制 使用场景 优缺点 Java 代码示例 PushConsumer 定义与概述 原理机制 使用场景 优缺点 Java 代码示例 总结 前言 RocketMQ中的消…

【2024高教社杯全国大学生数学建模竞赛】B题 生产过程中的决策问题——解题思路 代码 论文

目录 问题 1&#xff1a;抽样检测方案的设计问题 2&#xff1a;生产过程中的决策问题 3&#xff1a;多工序、多零配件的生产决策问题 4&#xff1a;重新分析次品率题目难度分析1. 统计检测方案设计的复杂性&#xff08;问题 1&#xff09;2. 多阶段生产决策的复杂性&#xff08…

常用排序算法(上)

目录 前言&#xff1a; 1.排序的概念及其运用 1.1排序的概念 1.2排序运用 1.3 常见的排序算法 2.常见排序算法的实现 2.1 堆排序 2.1 1 向下调整算法 2.1 2 建堆 2.1 3 排序 2.2 插入排序 2.1.1基本思想&#xff1a; 2.1.2直接插入排序&#xff1a; 2.1.3 插…

SQL进阶技巧:每年在校人数统计 | 区间重叠问题

目录 0 问题分析 1 数据准备 2 问题分析 3 小结 区间重叠问题 0 问题分析 有一个录取学生人数表 in_school_stu,记录的是每年录取学生的人数及录取学生的学制,计算每年在校学生人数。 1 数据准备 create table in_school_stu as ( select stack(5,1,2001,2,1200,2,2000…

Vue 中 watch 和 watchEffect 的区别

watch 和 watcheffect 都是 vue 中用于监视响应式数据的 api&#xff0c;它们的区别在于&#xff1a;watch 用于监视特定响应式属性并执行回调函数。watcheffect 用于更通用的响应式数据监视&#xff0c;但回调函数中不能更新响应式数据。Vue 中 watch 和 watchEffect 的区别 …

linux下的Socket网络编程教程

套接字概念 Socket本身有“插座”的意思&#xff0c;在Linux环境下&#xff0c;用于表示进程间网络通信的特殊文件类型。本质为内核借助缓冲区形成的伪文件。与管道类似的&#xff0c;Linux系统将其封装成文件的目的是为了统一接口&#xff0c;使得读写套接字和读写文件的操作…

Springboot工程配置https访问

背景 因为前端工程使用nginx配置了https访问&#xff0c;在https直接请求我们Springboot后端的http接口会报错。那么我们就需要配置使得我们后端的springboot服务支持https访问。 证书生成 在配置springboot工程https之前&#xff0c;我们需要生成自签名证书以及Spring Boot…

从材料到应用:螺杆支撑座材质选择的多样性与精准性!

支撑座是连接丝杆和电机的轴承固定座&#xff0c;其材料的选择直接影响使用效果。那么&#xff0c;大家知道螺杆支撑座常用的材质有哪些吗&#xff1f; 1、高碳钢&#xff1a;高碳钢因其高强度和良好的耐磨性&#xff0c;是螺杆支撑座制作中常用的材料。它能够很好地配合滚珠螺…

java 给list对象根据给定条数进行分组工具类

java 给list对象根据给定条数进行分组工具类 下面是一个示例的工具类&#xff0c;可以根据给定的条数对Student对象的List进行分组&#xff1a; import java.util.ArrayList; import java.util.List;public class StudentGroupUtil {public static List<List<Student&g…

ESD防静电监控系统助力电子制造行业转型升级

在电子制造行业中&#xff0c;静电危害不容小觑。ESD 防静电监控系统的出现&#xff0c;为行业转型升级带来强大助力。电子元件对静电极为敏感&#xff0c;微小的静电放电都可能损坏元件&#xff0c;影响产品质量。ESD 防静电监控系统能够实时监测生产环境中的静电状况&#xf…

C++——类和对象(2)

目录 一、类的默认成员函数 二、构造函数 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;特点 三、析构函数 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;特点 四、拷贝构造函数 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;特…

计算机考研真题知识点——2021(A)

目录 2021(A) 一、选择题 二、判断题 三、简答题 四、综合题 2021(A) 一、选择题 1、C语言程序是从程序中的main函数开始执行的。 2、 int x=2,y=3,z=4;x<z?y:z //的结果是? 3 4、若说明语句“int a[5],*p=a;”,则对数组元素的正确引用是() A、a[p] B、…

【2024-2025源码+文档+调试讲解】微信小程序的城市公交查询系统

摘 要 当今社会已经步入了科学技术进步和经济社会快速发展的新时期&#xff0c;国际信息和学术交流也不断加强&#xff0c;计算机技术对经济社会发展和人民生活改善的影响也日益突出&#xff0c;人类的生存和思考方式也产生了变化。传统城市公交查询管理采取了人工的管理方法…

【论文阅读】DETRs Beat YOLOs on Real-time Object Detection

文章目录 摘要一、介绍二、相关工作2.1 实时目标检测器2.2 端到端目标检测器 三、检测器的端到端速度3.1 分析 NMS3.2 端到端速度基准 四、实时 DETR4.1 模型概述4.2 高效混合编码器4.3不确定性最小的查询选择4.4 缩放的RT - DETR 五、实验5.1 与SOTA对比5.2 混合编码器的消融研…

【重构获得模式 Refactoring to Patterns】

重构获得模式 Refactoring to Patterns 面向对象设计模式是“好的面向对象设计”&#xff0c;所谓“好的面向对象设计”指的是那些可以满足“应对变化&#xff0c;提高复用”的设计。 现代软件设计的特征是“需求的频繁变化”。设计模式的要点是“寻找变化点&#xff0c;然后…

Spark2.x 入门: KMeans 聚类算法

一 KMeans简介 KMeans 是一个迭代求解的聚类算法&#xff0c;其属于 划分&#xff08;Partitioning&#xff09; 型的聚类方法&#xff0c;即首先创建K个划分&#xff0c;然后迭代地将样本从一个划分转移到另一个划分来改善最终聚类的质量。 ML包下的KMeans方法位于org.apach…

大语言模型LLM权重4bit向量量化(Vector Quantization)/查找表量化基本原理

参考 https://apple.github.io/coremltools/docs-guides/source/opt-palettization-overview.html https://apple.github.io/coremltools/docs-guides/source/opt-palettization-algos.html Apple Intelligence Foundation Language Models 苹果向量量化&#xff1a; DKM:…

在VMware虚拟机中编译文件的时候报错:找不到头文件ft2build.h

以下是报错内容&#xff0c;提示说找不到头文件ft2build.h freetype_show_font.c:12:10: fatal error: ft2build.h: No such file or directory #include <ft2build.h> ^~~~~~~~~~~~ compilation terminated. 在编译之前已经交叉编译了freetype&#xff0c;…

ic验证 -秋招

config db 用法&#xff1a; 传递virtual interface到环境中&#xff1b;配置单一变量值&#xff0c;例如int、string、enum等&#xff1b;传递配置对象&#xff08;config_object&#xff09;到环境&#xff1b; uvm_config_db #(type)::get( //ty…