--- java数据结构 map set ---

java中map 和 set的底层实现是通过搜索树和哈希函桶来实现 

搜索树

二叉搜索树有叫二叉排序树 他具有以下的特点

若存在左节点,那么他左节点的值一定小于根节点

若存在右节点,那么他右节点的值一定大于根节点

它的左右子树也是搜索树

对他进行中序遍历会的到一个升序的数组,且能达到去重的效果

二叉搜索树的实现

字段的实现

二叉树的插入

先找到要插入的位置,在插入时和节点的值比较,若小于该节点的值就往做边走,大于就往右边走

,这样一直走到null,那么这个位置就是我们要插入的位置,但是我们没有这个位置的父节点,所以需要一个parent来记录父节点

非递归

递归

查找

其实在实现插入的时后也就随便实现了查找,在给二叉树找到合适的插入位置时,当该值和节点值相同时就返回true 若没有那就返回false

删除

找到要删除的值对于的节点

删除比较麻烦 要分3中情况考虑

 

1,若删除的节点的左节点为空 ,那么直接删除该节点就好 

2,若右节点为空,那么也是直接删除节点就好

3,如果左右都不为空 那么就不呢直接删除节点了,因为左右还要节点,这要使用左边节点替代?还是右边?且左右节点都可能右节点的,显然不行

那么我们可以使用替换删除,使用15左树最大的值或者右树最小的值去取代15

搜索树是否创建成功,可以使用中序遍历来检查,正确的搜索树中序遍历会的到一个升序的数组

map set 是一种专门用来进行搜索的数据结构,搜索的效率和他实例化子类(Tree  hash)有关

模型

一般吧查找数据的关键字称为key 而与key对应的值就是value

K-V模型 比如查找单词 和对应单词的出现次数 <单词,出现的次数> 对于的数据结构时Map

纯K模型 只有Key 对于的数据结构是Set

map的使用

put(key,value)

插入数据在map中 key独一无二的

get(key)根据key返回对应的value
containsKey(key)

判断key是否存在于map中

返回值时boolean类型

containsValue(value)

判断value是否存在于map中

返回值时boolean类型

getOrDefault(key,default)

获得key对应的value,如果

不存在那么就返回default的值

isEmpty()map是不是为空
clear()清空map
remove(key)

删除对应key-value键值,并

返回key对应的value

remove(key,value)

删除对应的key-value键值

返回值时boolean类型

size()返回键值对个数
replace(key,value)

将key对应的value修改为传

入的value值,并返回的是key

未修改前的值

repalce(key,oldValue,newValue)

将key对应的oldValue修改为

newValue对应的值,返回值是

boolean类型,若k-v不匹配,那么

替换会失败

toString()

返回一个字符串,包括map所有

k-v数据

keySet()将map中的所有key以set返回
values()

放回value的可重复集,返回类型为

Collection<V> 

set的使用

add(key)插入key到set中
contains(key)

判断set中是否存在key

返回值是boolean类型

remove(key)删除key
size()返回set大小
clear()

清空set

toArray()将set中的所有key以数组形式返回
toArray(T[] a)             

将set中的所有key以数组形式返回

传入的a是是key类型的数组

返回的也是key类型的数组

isEmpty()set是否为空
iterator()返回一个迭代器 可用来遍历set
containsAll(Collection<?> c)

c集合中的值是否在set都存在,

若是那么就返回true 否false

removeAll(Collection<?> c)删除set中含有的集合c中的值
addAll(Collection<? extends E> c)将c中的所有值加到set中,会去重

map和set

map的底层结构

TreeMapHashMap
底层结构红黑树(也是搜索树)哈希桶

插入,删除,查找

时间复杂度

O(logN)O(1)
是否有序关于k有序无序
删除 插入 查找区别需要进行元素之间的比较通过哈希函数直接进行查找
适用范围需要key有序的情况下不在乎有无序,需要更高的效率

set的底层结构

TreeSetHashSet
底层结构红黑树哈希桶

插入,删除,查找

时间复杂度

O(logN)O(1)
是否有序关于k有序无序
删除 插入 查找区别需要进行元素之间的比较通过哈希函数直接进行查找
适用范围需要key有序的情况下不在乎有无序,需要更高的效率

哈希表

在顺序结构和树结构中进行数据的查询时,因为没有与查找的数据对应的关键码,所以在查找数据时会进行多次的数据之间的比较,而就是这些比较会大大增加我们的查找时间,所以时间复杂度会到达logN 或n^2这么高

而理想的查找查找方式是不同过任何比较,一次就找到这个数据,那么如果构造一种数据结构,他可以将数据和数据的关键码进行一一映射的关系,通过这个关键码就可以联系到该数据的位置,那么他的时间复杂度就可以达到O(1)

向该数据结构中插入数据

通过插入该函数的关键码来计算出该数据的储存位置,并吧该数据储存在该位置

查找数据

也是通过关键码计算出该数据的储存位置,在该位置找到对饮的数据

这种方法便是哈希(散列)方法,据此对应的数据结构就是哈希表(散列表),将关键码转换为特殊的数值的函数便是哈希函数

粗略的哈希表的表示  

这样如果要找8这个数据,我们可以通过哈希函数计算出他对饮的下标便是0 然后直接arr[0]就得到了8 这样没有通过比较,一次变就找到了需要的数据

哈希冲突

对于俩个数据的关键字在哈希函数中计算出哈希地址可能会出现相同的值的情况,比如1 % 7 = 1    8 % 7 = 1 这种情况就叫做哈希冲突 或者是哈希碰撞,若有不同的数据通过哈希函数计算出相同的哈希地址那么就称这写数据叫做 "同义词"

避免

在哈希底层的空间大小是小于实际储存数据所需要的大小,因为要达到O(1)的访问速度,那么就需要用到数组,通过下标直接访问该位置,算出的哈希地址会是充满随机性的,数组的大小不够是经常的事,那么发生冲突就是难以避免的,而我们能做的也就是降低冲突率

减低冲突率的方法

哈希函数的设计

设计的哈希函数的定义域应该包含需要储存的所有关键码,如果散列表有m个地址,那么设计的哈希函数的定义域就该在0 ~ m-1之间

哈希函数计算出的哈希地址应该平均分布在定义域之间

哈希函数要足够简单

当然设计哈希函数是很困难的是,直接用java中给的就好

哈希函数设计的越好,他的冲突率就越低,但是不能避免哈希冲突的发生

负载因子调节

散列表的负载因子定义 a = 有效元素的个数 / 总的储存空间的大小

 因为表长的定值,所以a和储存和储存的元素个数的数量成正比,而储存的元素数量越多,那么他的发生哈希冲突的概率越高,在开发地址中冲突率应该在0.7~0.8之间,超过这个区间,那么在查找过程中发生哈希冲突的概率按曲线上升,会大大减低哈希表的查询效率

要降低负载因子的大小,要么减少储存的元素个数,当然这时不行的,那么就只有增大储存空间的大小

冲突解决

解决哈希冲突的俩总常用方式,开散列和闭散列

闭散列

闭散列 也叫开放定址法,当发生哈希冲突时,若哈希表为装满,那么说明还有空位置,那么就把这个数据放到这个空位中去,那么这个空位要怎么寻找呢

线性探测

将数据从发生哈希冲突的这个位置开始,向后寻找,找到空的为位置,那么就把这个值放到这里

.

对于闭散列,在删除时不能直接吧该数据直接改变,会影响之后数据的查询,比如如果删除了2这个数据,那么在之后查找22这个数据时,会发现计算到的哈希地址为2,为2这个位置为空,那么查询就出了错误

二次探测

线性探测的缺点是会产生冲突数据的冗余,因为该数据是直接向后找到空位然后储存

为了降低线性探测的冲突数据冗余的情况,适二次探测来将冗余数据分散开来储存

那么二次探测寻找空位置的方式就是:add = (x + i^2)% m,x是计算出的哈希地址,i是1,2,3……m是数组的大小

对与闭散列最大的缺点就是空间利用率低,这也是哈希的缺陷

开散列 --哈希桶(更合理的冲突解决方法)

开散列又叫开地址法(开链法),数组中储存的是一个链表,将发生冲突的元素储存在一个链表中

这样查找时秩序要遍历这个链表就能找到数据

当表中的a达到的负载因子,那么就要对数组进行resize,扩容数组时需要遍历整个哈希表,然后吧数据放到对应的位置上

若随着数据的插入越来越多,链表上的数据多与一定的数目之后(64),那么这时的查询效率会大大减低,所以这时又会将该链表转换为红黑树(高度比较平衡的搜索树),用来增加查询的效率

开散列的实现

字段设计

add

先计算储存的有效元素个数是否小于负载因子,若不是那么就要扩容了,是的话那么直接吧该值放到对应的下标中,放的时候要对下标进行判断,若这个下标已经有数据存在,那么就见该值插入这个数据后,

poll

通过哈希函数计算除该数据对应的下标,然后判断该下标是否存在数据,若有,那么遍历这个链表来找到对应数值并删除

是否存在该数据

和删除时查找删除数据一样的

判断是否需要扩容

但达到的负载因子大小后 扩容

遍历整个哈希桶,并将每个数据放到新扩容的桶中去

哈希桶实现其实是哈希函数+数组+链表实现的,不过既然已经存在了链表,那么为什么查找效率还是O(1)呢

那是因为即使有了链表,但我们仍然可以认为链表长度时个常数,查找所需的实际可以忽略

在java中进行哈希值的计算实际上调用的时HashCode这个类,而对key的比较是调用的是equals这个方法,所以如果要将自定义类储存在HashMap或者HashSet中的话,那么需要重写equals和HashCode这俩个方法

在java类的继承中Map是没有继承与collection接口,而Set是继承了collection接口

EDN~~

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

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

相关文章

Oracle架构之物理存储中各种文件详解

文章目录 1 物理存储1.1 简介1.2 数据文件&#xff08;data files&#xff09;1.2.1 定义1.2.2 分类1.2.2.1 系统数据文件1.2.2.2 撤销数据文件1.2.2.3 用户数据文件1.2.2.4 临时数据文件 1.3 控制文件&#xff08;Control files&#xff09;1.3.1 定义1.3.2 查看控制文件1.3.3…

大数据与人工智能:基础与应用的多维思考

大数据与人工智能&#xff1a;基础与应用的多维思考 前言一、时代定位与发展方向二、人工智能的本质与学科融合三、大数据和人工智能的构成要素与大众需求四、计算机系统结构与基础软件的重要性五、研究途径与领域知识的作用六、发展的态度与责任 前言 当下&#xff0c;大数据…

分布式学习02-CAP理论

文章目录 CAP三指标一致性可用性分区容错性 CAP不可能三角P存在的必要性CP理论AP理论 CAP理论对分布式系统的特性做了高度抽象&#xff0c;将其抽象为一致性、可用性、分区容错性。 并对特征间的冲突做了总结&#xff1a;CAP不可能三角。 CAP三指标 一致性&#xff08;Consis…

Windows环境Apache httpd 2.4 web服务器加载PHP8:Hello,world!

Windows环境Apache httpd 2.4 web服务器加载PHP8&#xff1a;Hello&#xff0c;world&#xff01; &#xff08;1&#xff09;首先需要安装apache httpd 2.4 web服务器&#xff1a; Windows安装启动apache httpd 2.4 web服务器-CSDN博客文章浏览阅读222次&#xff0c;点赞5次&…

Git 下载及安装超详教程(2024)

操作环境&#xff1a;Win 10、全程联网 一、什么是Git&#xff1f; Git 是一个开源的分布式版本控制系统&#xff0c;由 Linus Torvalds 创立&#xff0c;用于有效、高速地处理从小到大的项目版本管理。Git 是目前世界上最流行的版本控制系统&#xff0c;被广泛用于软件开发中…

ECCV 2024 | 融合跨模态先验与扩散模型,快手处理大模型让视频画面更清晰!

计算机视觉领域顶级会议 European Conference on Computer Vision&#xff08;ECCV 2024&#xff09;将于9月29日至10月4日在意大利米兰召开&#xff0c;快手音视频技术部联合清华大学所发表的题为《XPSR: Cross-modal Priors for Diffusion-based Image Super-Resolution》——…

安防监控/视频系统EasyCVR视频汇聚平台如何过滤134段的告警通道?

视频汇聚/集中存储EasyCVR安防监控视频系统采用先进的网络传输技术&#xff0c;支持高清视频的接入和传输&#xff0c;能够满足大规模、高并发的远程监控需求。平台支持国标GB/T 28181协议、部标JT808、GA/T 1400协议、RTMP、RTSP/Onvif协议、海康Ehome、海康SDK、大华SDK、华为…

基于Zynq SDIO WiFi移植三(支持2.4/5G)

应用问题-WIFI作为AP-hostapd多次连接 设备作为WIFI热点时&#xff0c;连接出现了下述问题&#xff1a; 1 手机连接需要三次&#xff0c;三次都需要输入密码&#xff1b; 2 平板连接需要三次&#xff0c;三次都需要输入密码&#xff1b; 3 电脑连接需要一次&#xff0c;无感…

计算机视觉——图像修复综述篇

目录 1. Deterministic Image Inpainting 判别器图像修复 1.1. sigle-shot framework (1) Generators (2) training objects / Loss Functions 1.2. two-stage framework 2. Stochastic Image Inpainting 随机图像修复 2.1. VAE-based methods 2.2. GAN-based methods …

YOLOv11改进 | Conv篇 | YOLOv11引入SKConv

1. SKConv介绍 1.1 摘要:在标准卷积神经网络(CNN)中,每层中阿尔蒂神经元的感受野被设计为共享相同的大小。在神经科学界众所周知,视觉皮层神经元的感受野大小受到刺激的调制,这在构建CNN时很少考虑。我们在CNN中提出了一种动态选择机制,允许每个神经元根据输入信息的多…

[深度学习][python]yolov11+deepsort+pyqt5实现目标追踪

【算法介绍】 YOLOv11、DeepSORT和PyQt5的组合为实现高效目标追踪提供了一个强大的解决方案。 YOLOv11是YOLO系列的最新版本&#xff0c;它在保持高检测速度的同时&#xff0c;通过改进网络结构、优化损失函数等方式&#xff0c;提高了检测精度&#xff0c;能够同时处理多个尺…

【嵌入式软件-数据结构与算法】01-数据结构

摘录于老师的教学课程~~(*๓╰╯๓)~~内含链表、队列、栈、循环队列等详细介绍~~ 基础知识系列 有空再继续更~~~ 目录 【链表】 一、单链表 1、存储结构&#xff1a;带头结点的单链表 2、单链表结点类型的定义 3、创建单链表 1&#xff09;头插法 2&#xff09;尾插法 …

Python办公自动化之Word

在现代办公环境中&#xff0c;自动化无疑是提升工作效率的关键。特别是处理文档的工作&#xff0c;很多人可能花费大量时间在重复性任务上。那么&#xff0c;有没有一种方法可以让我们用 Python 来自动化 Word 文档的操作呢&#xff1f;今天&#xff0c;我们来聊聊如何用 Pytho…

k8s-集群部署1

k8s-集群部署1 一、基础环境准备二、docker环境准备三、k8s集群部署1.kubeadm创建集群2.使用kubeadm引导集群 总结 一、基础环境准备 首先&#xff0c;需要准备三个服务器实例&#xff0c;这里我使用了阿里云创建了三个实例&#xff0c;如果不想花钱&#xff0c;也可以在VM上创…

windows配置C++编译环境和VScode C++配置(保姆级教程)

1.安装MinGW-w64 MinGW-w64是一个开源的编译器套件&#xff0c;适用于Windows平台&#xff0c;支持32位和64位应用程序的开发。它包含了GCC编译器、GDB调试器以及其他必要的工具&#xff0c;是C开发者在Windows环境下进行开发的重要工具。 我找到了一个下载比较快的链接&#…

初识Linux · 自主Shell编写

目录 前言&#xff1a; 1 命令行解释器部分 2 获取用户命令行参数 3 命令行参数进行分割 4 执行命令 5 判断命令是否为内建命令 前言&#xff1a; 本文介绍是自主Shell编写&#xff0c;对于shell&#xff0c;即外壳解释程序&#xff0c;我们目前接触到的命令行解释器&am…

技术成神之路:设计模式(十八)适配器模式

介绍 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许接口不兼容的类可以协同工作&#xff0c;通过将一个类的接口转换成客户端所期望的另一个接口&#xff0c;使得原本由于接口不兼容而不能一起工作的类可以一起工作。 1.定义 适配…

基础算法--枚举

枚举算法是一种简单而有效的算法&#xff0c;它通过枚举所有可能的情况来解决问题。它通常用于解决问题规模比较小的问题&#xff0c;因为它的时间复杂度很高&#xff0c;随着问题的规模增加&#xff0c;算法的效率会急剧下降。 枚举算法的基本思路是通过循环遍历所有可能的情…

CSS实现服务卡片

CSS实现服务卡片 效果展示 CSS 知识点 回顾整体CSS知识点灵活运用CSS知识点 页面整体布局 <div class"container"><div class"card"><div class"box"><div class"icon"><ion-icon name"color-pal…

记录一次病毒启动脚本

在第一次下载软件时&#xff0c;目录中配了一个使用说明&#xff0c;说是需要通过start.bat 这个文件来启动程序&#xff0c;而这个 start.bat 就是始作俑者&#xff1a; 病毒作者比较狡猾&#xff0c;其中start.bat 用记事本打开是乱码&#xff0c;但是可以通过将这个批处理…