二叉搜索树 , Set 和 Map (JAVA)

news2024/11/20 22:38:45

二叉搜索树

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

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

二叉搜索树的插入非常简单:

  1. 从根节点开始比较,如果大于根节点就遍历右子树,小于根节点就遍历左子树
  2. 对所有的子树都进行如上操作
  3. 直到遍历到空节点,将待插入元素插入此空节点
public class BinarySearchTree {

    public static class TreeNode {
        public int key;
        public TreeNode left;
        public TreeNode right;

        TreeNode(int key) {
            this.key = key;
        }
    }

    public TreeNode root;
    /**
     * 插入一个元素
     */
    public boolean insert(int key) {
        TreeNode tmp = new TreeNode(key);
        if (this.root == null) {
            this.root = tmp;
            return true;
        }
        TreeNode privat = this.root;
        TreeNode p1 = this.root;
        while (p1 != null) {
            privat = p1;
            if (p1.key > key) {
                p1 = p1.left;
            }else {
                p1 = p1.right;
            }
        }
        if (privat.key > key) {
            privat.left = tmp;
        }else {
            privat.right = tmp;
        }
        return true;
    }
}

二叉搜索树的查找:

  1. 从根节点开始比较,如果大于根节点就遍历右子树,小于根节点就遍历左子树
  2. 对所有的子树都进行如上操作
    //查找key是否存在
    public TreeNode search(int key) {
        if (this.root == null){
            return null;
        }
        TreeNode tmp = this.root;
        while (tmp != null) {
            if (tmp.key > key) {
                tmp = tmp.left;
            }else if (tmp.key < key) {
                tmp = tmp.right;
            }else {
                return tmp;
            }
        }
        return null;
    }

二叉搜索树的删除比较复杂因为要保证删除之后的树依旧是一颗二叉搜索树

二叉搜索树的删除:

分两种情况:

  • 左树或者右树为空
  1. 当待删除节点左树为空就令待删除节点的双亲指向其右子树
  2. 当待删除节点右树为空就令待删除节点的双亲指向其左子树

  • 左右子树都不为空
  1. 找到右(左)子树最左(右)端的节点
  2. 交换两个结点的值
  3. 删除该节点

    //删除key的值
    public boolean remove(int key) {
        if (this.root == null) {
            return false;
        }
        TreeNode tmp = this.root;
        TreeNode privat = tmp;
        while (tmp != null) {
            if (tmp.key > key) {
                privat = tmp;
                tmp = tmp.left;
            }else if (tmp.key < key) {
                privat = tmp;
                tmp = tmp.right;
            }else {
                break;
            }
        }
        if (tmp == null) {
            return false;
        }
        //左树或者右树为空
        if (tmp.left == null || tmp.right == null) {

            if (tmp.left == null) {
                if (tmp == this.root) {
                    this.root = tmp.right;
                }else {
                    if (privat.left == tmp) {
                        privat.left = tmp.right;
                    }else {
                        privat.right = tmp.right;
                    }
                }

            }else {
           
                if (tmp == this.root) {
                    this.root = tmp.left;
                }else {
                    if (privat.left == tmp) {
                        privat.left = tmp.left;
                    }else {
                        privat.right = tmp.left;
                    }
                }
            }
        }else {
        //左右子树都不为空
            TreeNode a = tmp.right;
            while(a.left != null) {
                privat = a;
                a = a.left;
            }
            tmp.key = a.key;
            if (privat.left == a) {
                privat.left = a.right;
            }else {
                privat.right = a.right;
            }
        }
        return true;
    }

Set 和 Map

Map和set是一种专门用来进行搜索的容器或者数据结构,其搜索的效率与其具体的实例化子类有关。
一般把搜索的数据称为关键字(Key),和关键字对应的称为(Value),将其称之为Key-value的键值对。


两种模型:

  • 纯 key 模型:

             有一个英文词典,快速查找一个单词是否在词典中快速查找某个名字在不在通讯录中

  • Key-Value 模型:

             统计文件中每个单词出现的次数,统计结果是每个单词都有与其对应的次数:<单词,单词出现的次数>

Map.Entry

Map.Entry<K, V> 是Map内部实现的用来存放<key, value>键值对映射关系的内部类
里面有这几种方法:

方法解释
K getKey()返回 entry 中的 key
V getValue()返回 entry 中的 value
V setValue(V value)将键值对中的value替换为指定value

Map

  • Map是一个接口,不能直接实例化对象,如果要实例化对象只能实例化其实现类TreeMap或者HashMap
  • Map中存放键值对的Key是唯一的,value是可以重复的
  • TreeMap中插入键值对时,key不能为空,否则就会抛NullPointerException异常,value可以为空。但是HashMap的key和value都可以为空
  • Map中的Key可以全部分离出来,存储到Set中来进行访问(因为Key不能重复)。
  • Map中的value可以全部分离出来,存储在Collection的任何一个子集合中(value可能有重复)。
  • Map中键值对的Key不能直接修改value可以修改,如果要修改key,只能先将该key删除掉,然后再来进行重新插入。
     
    public static void main(String[] args) {
        Map<Integer,Integer> map = new HashMap<>();
        Map<Integer,Integer> map1 = new TreeMap<>();
    }
Map底层结构TreeMapHashMap
底层结构红黑树哈希桶
插入/删除/查找时间
复杂度
O(\log_{2}N)O(1)
是否有序关于Key有序无序
线程安全不安全不安全
插入/删除/查找区别需要进行元素比较通过哈希函数计算哈希地址
比较与覆写key必须能够比较,否则会抛出
ClassCastException异常
自定义类型需要覆写equals和
hashCode方法
应用场景需要Key有序场景下Key是否有序不关心,需要更高的
时间性能

方法解释
V get(Object key)返回 key 对应的 value
V getOrDefault(Object key, V defaultValue)返回 key 对应的 value,key 不存在,返回默认值
V put(K key, V value)设置 key 对应的 value
V remove(Object key)删除 key 对应的映射关系
Set<K> keySet()返回所有 key 的不重复集合
Collection<V> values()返回所有 value 的可重复集合
Set<Map.Entry<K, V>> entrySet()返回所有的 key-value 映射关系
boolean containsKey(Object key)判断是否包含 key
boolean containsValue(Object value)判断是否包含 value

Set

  • Set是继承自Collection的一个接口类
  • Set中只存储了key,并且要求key一定要唯一
  • TreeSet的底层是使用Map来实现的,其使用key与Object的一个默认对象作为键值对插入到Map中的
  • Set最大的功能就是对集合中的元素进行去重
  • 实现Set接口的常用类有TreeSet和HashSet,还有一个LinkedHashSet,LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。
  • Set中的Key不能修改,如果要修改,先将原来的删除掉,然后再重新插入
  • TreeSet中不能插入null的key,HashSet可以
Set底层结构TreeSetHashSet
底层结构红黑树哈希桶
插入/删除/查找时间
复杂度
O(\log_{2}N)O(1)
是否有序Key有序不一定有序
线程安全不安全不安全
插入/删除/查找区别按照红黑树的特性来进行插入和删除

1. 先计算key哈希地址

2. 然后进行插入和删除

比较与覆写key必须能够比较,否则会抛出
ClassCastException异常
自定义类型需要覆写equals和
hashCode方法
应用场景需要Key有序场景下Key是否有序不关心,需要更高的
时间性能

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

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

相关文章

北京开发APP需要多少钱

北京开发一个移动应用&#xff08;APP&#xff09;的费用因多种因素而异&#xff0c;包括项目的规模、复杂性、所需功能、设计要求、技术选择、开发团队的经验和地理位置等。一般来说&#xff0c;北京的APP开发费用通常较高&#xff0c;因为这是中国的主要技术和创新中心之一&a…

【云备份项目】:环境搭建(g++、json库、bundle库、httplib库)

文章目录 1. g 升级到 7.3 版本2. 安装 jsoncpp 库3. 下载 bundle 数据压缩库4. 下载 httplib 库从 Win 传输文件到 Linux解压缩 1. g 升级到 7.3 版本 &#x1f517;链接跳转 2. 安装 jsoncpp 库 &#x1f517;链接跳转 3. 下载 bundle 数据压缩库 安装 git 工具 sudo yum…

嵌入式Linux应用开发-驱动大全-第一章同步与互斥①

嵌入式Linux应用开发-驱动大全-第一章同步与互斥① 第一章 同步与互斥①1.1 内联汇编1.1.1 C语言实现加法1.1.2 使用汇编函数实现加法1.1.3 内联汇编语法1.1.4 编写内联汇编实现加法1.1.5 earlyclobber的例子 1.2 同步与互斥的失败例子1.2.1 失败例子11.2.2 失败例子21.2.3 失败…

IDEA中的神仙插件——Smart Input (自动切换输入法)

推荐专栏&#xff1a;开发环境配置攻略 致力于记录学习过程中各种软件的安装及环境配置操作&#xff0c;并提供详细的步骤说明和丰富的配图。涵盖了 Java、Python、IntelliJ IDEA、Tomcat、MySQL 等常见开发工具和服务器组件的配置&#xff0c;为初学者提供一个实用、全面的配置…

Sentinel-2波段合成

Sentinel-2波段合成 在上一篇博客中下载了Sentinel-2数据&#xff0c;他有13个波段的.jp2文件&#xff0c;下面选取需要使用的波段进行合成。 导入了B2&#xff08;蓝色&#xff09;、B3&#xff08;绿色&#xff09;、B4&#xff08;红色&#xff09;、B8&#xff08;近红外&…

第一章 概论

第一章 概论 引言基本概念和术语数据、数据元素和数据项数据的逻辑结构数据的存储结构&#xff08;物理结构&#xff09;运算 算法及描述算法分析时间复杂度空间复杂度 牛刀小试 引言 数据结构是指一组相互之间存在一种或多种特定关系的数据的组织方式和它们在计算机内的存储方…

【Java 进阶篇】JDBC PreparedStatement 详解

在Java中&#xff0c;与关系型数据库进行交互是非常常见的任务之一。JDBC&#xff08;Java Database Connectivity&#xff09;是Java平台的一个标准API&#xff0c;用于连接和操作各种关系型数据库。其中&#xff0c;PreparedStatement 是 JDBC 中一个重要的接口&#xff0c;用…

ARM---实现1-100求和任务

.text .globl _start_start:mov r0, #0x1mov r1, #0x1 给r1加一固定1不变mov r2, #0x64 100判断bl sumcmp r1, r2 sum:addcc r1, r1,#0x1 r1自增addcc r0, r0, r1 r0求和movcc pc,lrstop:b stop.end

Linux shell编程学习笔记6:查看和设置变量的常用命令

上节我们介绍了变量的变量命名规则、变量类型、使用变量时要注意的事项&#xff0c;今天我们学习一下查看和设置变量的一些常用命令&#xff0c;包括变量的提升&#xff0c;有些命令在之前的实例中已经使用过了。 一、 echo &#xff1a;查看变量的值 语法格式&#xff1a;ech…

金融机构操作风险与内控合规的介绍

目录 一.前言 术语 二.功能设计 三.部分功能简介 流程管理 流程清单 流程详情 流程重检 流程重检反馈 风险与控制自我评估&#xff08;RCSA&#xff09; 评估计划管理 评估结果管理 关键风险指标&#xff08;KRI&#xff09; 指标库管理 基础数据项录入 指标监测…

电阻的基础与应用

文章目录 电阻的基础与应用电阻的介绍与分类电阻介绍电阻的分类碳膜/金属膜电阻厚膜/薄膜电阻功能性电阻&#xff08;光敏/热敏/压敏&#xff09;特殊电阻&#xff08;绕线电阻/水泥电阻/铝壳电阻&#xff09; 电阻的主要厂家与介绍国外厂家VISHAY(威世)KOA(兴亚)Kyocera(京瓷)…

电脑右键新建记事本不见了--设置恢复篇(无需操作注册表)

电脑右键新建记事本不见了–设置恢复篇&#xff08;无需修改注册表&#xff09; 电脑不知怎么想右键新建记事本结果竟然不见了&#xff0c;搜寻网上的都是什么修改注册表&#xff0c;粘贴代码修复&#xff08;感觉太复杂了&#xff09;&#xff0c;这里介绍通过设置内重新对记…

❋JQuery的快速入门 1 了解jq

目录 选定元素 1. jquery基本选择器 2. 层级选择器 3. 元素精确定位 4. 内容选择器 5. 属性选择器及其他 元素解析 操作元素内容与样式 操作文档的文本结构 jq事件 jq动画 JQuery 是一个“写的更少&#xff0c;但做的更多”的轻量级 JavaScript 库。 使用前要先导入…

自定义实现hashmap-python

前文 ​ 今天这篇文章给大家讲讲hashmap&#xff0c;这个号称是所有前后端工程师都会的数据结构。 hashmap基本结构 ​ hashmap这个数据结构其实并不难&#xff0c;它的结构非常清楚&#xff0c;说白了就是一个定长的链表&#xff0c;这个数组的每一个元素都是一个链表。我们…

AutoForm R11安装说明视频教程

AutoForm R11安装说明视频教程 安装AutoForm.Forming.R11.Win64_01在安装过程中选择安装许可证服务器并输入许可证服务器2375localhost和完成 安装 -继续解文件夹复制2个文件并在C:\Program files\RLM_v14.1BL3上替换它们作为管理员运行RLM.exe 确保您的系统环境如下所示&a…

(unordered)map和set封装(底层红黑树)

map和set封装 文章目录 map和set封装设计问题&#xff08;知其所以然&#xff09;为什么要对iterator进行封装&#xff1f;为什么要引入Self Ref Ptr这些模板参数&#xff1f;为什么是试图从non_const转变为const&#xff0c;而不是const转为non_const如何解决 为什么说能加con…

vscode 乱码解决

windows 10 系统 vs code 编译运行和调试 C/C_vscode windows编译_雪的期许的博客-CSDN博客 VS Code默认文件编码时UTF-8&#xff0c;这对大多数情况是没有问题的&#xff0c;却偏偏对C/C有问题。如果以UTF-8编码保存C/C代码&#xff0c;那么只能输出英文&#xff0c;另外使用…

【Java-LangChain:使用 ChatGPT API 搭建系统-4】评估输入-分类

第三章&#xff0c;评估输入-分类 如果您正在构建一个允许用户输入信息的系统&#xff0c;首先要确保人们在负责任地使用系统&#xff0c;以及他们没有试图以某种方式滥用系统&#xff0c;这是非常重要的。 在本章中&#xff0c;我们将介绍几种策略来实现这一目标。 我们将学习…

优先级队列--合并多个有序链表

如果本文章有不懂的&#xff0c;请进入预习链接&#xff1a;优先级队列_加瓦不加班的博客-CSDN博客 这道题目之前解答过&#xff0c;现在用刚学的优先级队列来实现一下 题目中要从小到大排列&#xff0c;因此选择用小顶堆来实现&#xff0c;自定义小顶堆如下 //小顶堆的操作与…

图像处理与计算机视觉--第五章-图像分割-Canny算子

文章目录 1.边缘检测算子分类2.Canny算子核心理论2.1.Canny算子简单介绍2.2.Canny算子边缘检测指标2.3.Canny算子基本原理 3.Canny算子处理流程3.1.高斯滤波去噪声化3.2.图像梯度搜寻3.3.非极大值抑制处理3.4.双阈值边界处理3.5.边界滞后技术跟踪3.6.Canny算子边缘检测的特点 4…