hashmap中为什么使用红黑树?

2023-11-17

在回答这个问题之前,我们先了解一下有关二叉树的基本内容。

①二叉排序树(又称二叉查找树):

1)若左子树不为空,则左子树上所有结点的值均小于根结点的值。
2)若右子树不为空,则右子树上所有结点的值均大于根节点的值。
3)左右子树也为二叉排序树。

②平衡二叉树(AVL树):

是一种二叉查找树,当且仅当两个子树的高度差不超过1时,这个树是平衡二叉树。

③红黑树:

是许多二叉查找树中的一种,不严格的平衡二叉树,即不像AVL那样要求节点的 |balFact| <= 1,它只要求部分达到平衡,但是提出了为节点增加颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决。它能保证在最坏的情况下,基本动态集合操作时间为O(lgn).

问题1:为什么不使用二叉排序树?

问题主要出现在二叉排序树在添加元素的时候极端情况下会出现线性结构。

举例说明:由于二叉排序树左子树所有节点的值均小于根节点的特点,如果我们添加的元素都比根节点小,会导致左子树线性增长,这样就失去了用树型结构替换链表的初衷,导致查询时间增长。所以这是不用二叉查找树的原因。

问题2:为什么不使用平衡二叉树呢?

①红黑树不追求"完全平衡",即不像AVL那样要求节点的 |balFact| <= 1,它只要求部分达到平衡,但是提出了为节点增加颜色,红黑是用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决,而AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多。
就插入节点导致树失衡的情况,AVL和RB-Tree都是最多两次树旋转来实现复衡rebalance,旋转的量级是O(1)
删除节点导致失衡,AVL需要维护从被删除节点到根节点root这条路径上所有节点的平衡,旋转的量级为O(logN),而RB-Tree最多只需要旋转3次实现复衡,只需O(1),所以说RB-Tree删除节点的rebalance的效率更高,开销更小!
AVL的结构相较于RB-Tree更为平衡,插入和删除引起失衡,如2所述,RB-Tree复衡效率更高;当然,由于AVL高度平衡,因此AVL的Search效率更高啦。
针对插入和删除节点导致失衡后的rebalance操作,红黑树能够提供一个比较"便宜"的解决方案,降低开销,是对search,insert ,以及delete效率的折衷,总体来说,RB-Tree的统计性能高于AVL.
故引入RB-Tree是功能、性能、空间开销的折中结果。
② AVL更平衡,结构上更加直观,时间效能针对读取而言更高;维护稍慢,空间开销较大。
③ 红黑树,读取略逊于AVL,维护强于AVL,空间开销与AVL类似,内容极多时略优于AVL,维护优于AVL。
基本上主要的几种平衡树看来,红黑树有着良好的稳定性和完整的功能,性能表现也很不错,综合实力强,在诸如STL的场景中需要稳定表现。

问题3:为什么不使用b+树呢?

B+树在数据库中被应用的原因是其“矮胖”的特点,B+树的非叶子结点不存储数据,所以每个结点能存储的关键字更多。所以B+树更能应对大量数据的情况。jdk1.7中的HashMap本来是数组+链表的形式,链表由于其查找慢的特点,所以需要被查找效率更高的树结构来替换。如果用B+树的话,在数据量不是很多的情况下,数据都会“挤在”一个结点里面。这个时候遍历效率就退化成了链表。
结论:b+树不属于二叉树,因为二叉查找树的查找效率是最高的,如果内存能装下完整的树,最好使用二叉查找树,b+树是退而求其次的方式。

问题4:为什么不使用跳跃表呢?

跳跃表也可以很快的查询数据,但是 HashMap 的 各个Entry 之间并没有内在的排序关系,跳表需要元素之间存在排序关系,否则就无法跳跃查找不是吗?

TreeMap 的并发实现 ConcurrentSkipListMap 就是使用的跳表。

再者就是跳跃表因为要定义多级指针,是以空间换时间的数据结构,红黑树树不需要额外的空间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

hashmap中为什么使用红黑树? 的相关文章

随机推荐

  • Pandas玩转数据透视表,用它就够了~

    大家好 我是丁小杰 对于数据透视表 相信对于 Excel 比较熟悉的小伙伴都知道如何使用它 并了解它的强大之处 而在pandas中要实现数据透视就要用到pivot table了 导入示例数据 首先导入演示的数据集 import pandas
  • 【C++】STL之栈(stack)介绍

    栈 stack 栈是一种运算受限的线性表 限定仅在表尾进行插入和删除的操作 插入 push 弹出 pop 其特性就是先进后出 即先插入的元素最后才能弹出 大家可以把栈想象成一个弹夹 你只能在顶层一颗一颗装入子弹 先装的子弹在最底层 打出时也
  • 学什么副业前景好?学一个什么副业比较好?自学副业有哪些?

    很多公司不希望自己的员工做副业 主要还是担心员工做副业会影响到工作 如果员工在下班后的空闲时间搞搞副业 那公司就没法管了呀 你平时下班后的空闲时间都做些什么 学什么副业前景好 1 自学ps 现在很多影楼 摄影工作室 电商商家会把自己拍摄的照
  • JVM调优参数归纳汇总

    GC通常参数 Xss 每个线程的栈大小 Xms 初始堆大小 默认物理内存的1 64 Xmx 最大堆大小 默认物理内存的1 4 Xmn 新生代大小 XX ParallelGCThreads 指定GC工作的线程数量 XX MinHeapSize
  • 查询局域网电脑的IP,端口号,MAC地址

    网上看到很多都是使用nmap工具 这个工具我没有使用过 我自己实现nmap工具的功能 首先我们查询局域网内有哪些电脑是alive的 下面我写了一个脚本 ping sh 这样局域网内哪些电脑的ip是alive的就可以知道 下面来查看对于IP的
  • leetcode--55--跳跃游戏

    题目描述 给定一个非负整数数组 你最初位于数组的第一个位置 数组中的每个元素代表你在该位置可以跳跃的 最大长度 判断你是否能够到达最后一个位置 示例 1 输入 2 3 1 1 4 输出 true 解释 我们可以先跳 1 步 从位置 0 到达
  • 【ChatGPT】基于WSL+Docker的ChatGPT PLUS共享服务部署

    最近买了ChatGPT PLUS服务 想通过web服务将它共享给其他人使用 搜了一下目前GitHub上比较热门的服务有 ChatGPT Next Web chatgpt web share 其中chatgpt web share支持API和
  • 【uni-app】css 关于 calc()函数计算无效

    计算符 注 计算 符前后都需要空格 否则计算无效
  • 华为OD机试真题 Java 实现【最多提取子串数目】【2023Q1 100分】

    一 题目描述 给定由 a z 26 个英文小写字母组成的字符串 A和 B 其中A中可能存在重复字母 B 中不会存在重复字母 现从字符串 A 中按规则挑选一些字母 可以组成字符串 B 挑选规则如下 同一个位置的字母只能被挑选一次 被挑选字母的
  • ue4加载本地版本_【虚幻4】创建本地数据库

    简介 这里我们主要通过使用Data table实现本地数据库 Data table可以用来保存一些用户配置 或者常用变量 或者用来实时更新外部表格数据到虚幻4中 一 创建Data table 1 首先创建Structure结构 这里我已经创
  • 我用什么写Python?

    通常来说 每个程序员都有自己趁手的兵器 代码编辑器 你要是让他换个开发环境 恐怕开发效率至少下降三成 然而 每个人对编辑器的喜好各不相同 甚至引发出诸如 神的编辑器 与 编辑器之神 这种信仰之争 但也正由此可见 个性化的编辑器对于一个程序员
  • 【FICO系列】SAP FICO 凭证错误:BKPFF$PRDCLN800在FI中达到的项目最大编号

    公众号 SAP Technical 本文作者 matinal 原文出处 http www cnblogs com SAPmatinal 原文链接 FICO系列 SAP FICO 凭证错误 BKPFF PRDCLN800在FI中达到的项目最大
  • 无法访问目标主机的原因及其和请求超时的区别

    使用ping命令时经常会遇到这两种情况 就表示网络出了问题 无法访问目标主机的原因 可以看到 无法访问目标主机 是来自一个IP的回复 实际上那个IP是一个路由器 因此 无法访问目标主机 实际上数据是发出去并且收到回复的 只不过收到的回复是别
  • 数据结构和算法(递归概念、迷宫回溯问题和八皇后问题代码实现)

    递归的概念 递归能够做解决什么问题 使用递归时需要注意的问题 递归的第一个应用 迷宫回溯问题 迷宫模拟 定义一个8 7的数组模拟迷宫 1表示围墙 0表示可以走的路 图中左上红圈为起点 右下红圈为终点 利用代码找到从起点到终点的路径 使用递归
  • 【Python】代码实现LL(1),LR(1)上下文无关文法(Stack()类)

    任务要求 针对书上第三章中的表达式文法 采用LL 1 LR 1 进行分析 相关文法 需要进行消除左递归等操作 顺手分享一下课本资源好了 可能不是最新版 排版略有点别扭 后文的书上内容就是指这本书 编译原理 陈意云 文字版 提取码 e0ag
  • Android Studio如何添加工程(project)为library(针对非gradle)

    这篇文章还是针对非gradle build的工程 gradle build有一些差别 在Eclipse要引用别的工程为本工程的library很简单 但是在Android Studio还是稍稍有点小复杂的 那如何引用别的工程为本工程的libr
  • 网络编程——TCP并发服务器模型

    1 多线程中的newfd 能否修改成全局 不行 为什么 因为如果是全局变量 文件描述符就是唯一的 所有的客户端都会在同一个文件描述符通信 2 多线程中分支线程的newfd能否不另存 直接用指针间接访问主线程中的newfd 不行 为什么 如果
  • 微信小程序-仿智行火车票12306

    微信小程序 仿智行火车票12306 微信小程序 仿智行火车票12306 主页有轮播图 有导航栏 有个人中心 可以实现火车票 飞机票 汽车票的选择 适合初学者学习 下面是示例图片 下载链接 https download csdn net do
  • Linux系统图形界面和命令行界面之间的切换

    一 系统不在虚拟机中的情况 使用ctrl alt F1 6切换到命令行界面 ctrl alt F7切换到图形界面 二 系统在虚拟机中的情况 Ctrl Alt shift F1 6切换到命令行界面 使用Alt F7返回到图形界面 注 以上方法
  • hashmap中为什么使用红黑树?

    在回答这个问题之前 我们先了解一下有关二叉树的基本内容 二叉排序树 又称二叉查找树 1 若左子树不为空 则左子树上所有结点的值均小于根结点的值 2 若右子树不为空 则右子树上所有结点的值均大于根节点的值 3 左右子树也为二叉排序树 平衡二叉