红黑树

JDK1.8-HashMap源码分析

时光毁灭记忆、已成空白 提交于 2020-02-23 02:48:22
HashMap,用的再多不过的东西了,面试中也经常问到,但是总是会答不出来一个所以然,回答的都太表面,要么就表达不清楚。俗话说,表达不清或者不能够让别人听懂就是自己没有搞懂。所以我要好好整理一下HashMap了。 这篇文章以JDK1.8为基础,因为JDK1.8里面引入了红黑树,真的很有意思,如果要了解红黑树,可以去看看我写的一片文章,关于红黑树的。读懂了后再来分析HashMap会了解许多。首先对于分析任何一个源码,掌握其数据结构是最基本,也是分析源码最重要的,这是精华OK?那么HashMap的精华就是数组+链表+红黑树。 看到没有,HashMap的数据结构就是上面这个样子。它的最左边也就是它所实现的“hash”,是一个数组,这样访问某一个bucket可以达到O(1)的复杂度。右边分别对应着链表和红黑树,插入删除都非常方便,访问也非常快速。而在源码里面实际的数据结构这样子: HashMap中的经典类变量 transient Node < K , V > [ ] table ; 这个就是用来存储实际数据的,每个节点是一个Node的数据结构或者说对象吧,看你怎么理解,它只有在初次使用的时候才初始化,注意构造方法不会初始化它。而且他是一个数组,会根据需要来扩容,长度永远是2的幂。 //这个值构造方法里也没有参数指定,因为它是直接由Capacity*loadFractor

linux调度

一个人想着一个人 提交于 2020-02-20 18:06:16
调度的基本数据结构 1.每个cpu都有自己的一个struct rq, 里面有一个实时进程的struct rt_rq 和一个普通进程的struct cfs_rq。 在调度时,调度器首先会先去实时进程队列找是否有实时进程需要运行,如果没有才去CFS运行队列找是否有进程需要运行。 2.普遍进程的cfs_rq 定义如下 这里面的rb_root指向的就是红黑树的根节点,这个红黑树在CPU看起来就是一个队列,不断的取下一个应该运行的进程。 rb_leftmost指向的是最左面的节点 3.调度队列——红黑树,调度实体 完全公平调度算法CFS,CFS会为每一个进程安排一个虚拟运行时间vruntime。如果一个进程在运行,随着时间的增长,进程的vruntime将不断增大,但没有得到执行的进行vruntime将不变。 显然,那些vruntime少的,原来受到了不公平的对待,需要给它补上,所以会优先运行这样的进程。 高低优先级怎么处理?优先级其实就是一个数值,对于实时进程,优先级的范围是0-99;对于普通进程,优先级的范围是100-139.数值越小,优先级越高。 在计算vruntime的时候有一个公式 权重和nice数值有关系,nice越小权重就越大, NICE_0_LOAD是nice为0时的权重。所以从这个公式我们可以看出,高优先级(即nice值小的)的进程vruntime加的会少

红黑树

痞子三分冷 提交于 2020-02-20 13:01:40
改变颜色和旋转 变颜色的情况:当前节点父亲是红色,且它的祖父亲节点的另一个子节点也是红色(叔叔节点): 1.将父亲节点设置为黑色 2.将叔叔节点设为黑色 3.将祖父也就是父亲的父亲设为红色 4.把指针定义到祖父节点设为当前操作 左旋转: 左旋:当父亲节点为红色情况,叔叔的节点为黑色的情况,且当前的节点是右子树,左旋转以父节点作为左旋; 右旋转:当父亲节点为红色情况,叔叔的节点为黑色的情况,且当前的节点是左子树,右旋转以 1.将父节点变为黑色 2.将祖父节点变为红色(爷爷) 3.以祖父节点开始旋转 数据结构: Jdk1.7使用数组+链表 Jdk1.8使用数组+链表+红黑树(解决链表过长查询慢的问题) (当链表深度达到8的时候,就会采用红黑树存放,这时候时间复杂度为O (n ))变为O(log n) 扩容线程安全问题: Jdk1.7采用头插法,在数组扩容的时候容易导致死循环问题、Jdk1.8采用尾插入法解决了数组扩容容器导致死循环问题 来源: CSDN 作者: 君子志邦 链接: https://blog.csdn.net/u011488009/article/details/104358025

HashMap-treeifyBin()源码简读(JDK1.8)

拟墨画扇 提交于 2020-02-20 05:03:41
HashMap的treeifyBin()方法源码 final void treeifyBin ( Node < K , V > [ ] tab , int hash ) { //定义几个变量,n是数组长度,index是索引 int n , index ; Node < K , V > e ; //这里的tab指的是本HashMap中的数组,n为数字长度,如果数组为null或者数组长度小于64 if ( tab == null || ( n = tab . length ) < MIN_TREEIFY_CAPACITY ) //则调用resize()方法直接扩容,不转红黑树 resize ( ) ; //否则说明满足转红黑树条件,通过按位与运算取得索引index,并将该索引对应的node节点赋值给e,e不为null时 else if ( ( e = tab [ index = ( n - 1 ) & hash ] ) != null ) { //定义几个变量,hd代表头节点,tl代表尾节点 TreeNode < K , V > hd = null , tl = null ; do { //先把e节点转成TreeNode类型,并赋值给p TreeNode < K , V > p = replacementTreeNode ( e , null ) ; //如果尾节点tl为空

TreeMap的底层原理

此生再无相见时 提交于 2020-02-20 03:11:33
1 前言 本人使用的是jdk1.8版本。 2 Map集合继承结构 3 底层原理 TreeMap底层使用红黑树的结构进行数据的增删改查,红黑树是一种自平衡的二叉查找树,想了解红黑树推荐看看这篇博文: 30张图带你彻底理解红黑树 。学过数据结构的都知道二叉查找树是一种有序树,即进行中序遍历可以得到一组有序序列,所以TreeMap也是有序的Map集合。 在红黑树的加持下,TreeMap的众多方法,如:containsKey、get、put和reomve,都能保证log(n)的时间复杂度,这个效率可以说是相当高了。 /** * A Red-Black tree based {@link NavigableMap} implementation. * The map is sorted according to the {@linkplain Comparable natural * ordering} of its keys, or by a {@link Comparator} provided at map * creation time, depending on which constructor is used. * * <p>This implementation provides guaranteed log(n) time cost for the * {@code

IO 多路转接 epoll

☆樱花仙子☆ 提交于 2020-02-20 01:15:28
read 函数返回值 >0 :实际读到的字节数 =0 :socket中,表示对端关闭 close() -1 : 如果errno = EINTR 被异常中断。需要重启。 如果errno =EAGIN 或 EWOULDBLOCK 以非阻塞的方式读数据,但是没有数据。需要再次读 如果errno = ECONNRESET 说明连接被重置。需要close()。 移除监听队列 错误 突破 1024 文件描述符限制 cat /proc/sys/fs/file-max 当前计算机能打开的最大文件个数。受硬件影响 ulimit -a -->当前用户下的进程。默认打开文件件描述符个数 缺省 为 1024 修改: 打开 sudo vi /etc/security/limits.conf 写入 * soft nofile 65536 -->设置默认值 可以直接借助命令修改【注销用户 使其生效】 * hard nofile 100000 --》命令修改上限 命令修改: ulimit -n 21000 突破 1024 文件描述符限制 cat /proc/sys/fs/file-max 当前计算机能打开的最大文件个数。受硬件影响 ulimit -a -->当前用户下的进程。默认打开文件件描述符个数 缺省 为 1024 修改: 打开 sudo vi /etc/security/limits.conf 写入 *

Map源码会问哪些面试题

爷,独闯天下 提交于 2020-02-18 15:20:34
1 Map 整体数据结构类问题 1.1 说一说 HashMap 底层数据结构 答:HashMap 底层是数组 + 链表 + 红黑树的数据结构,数组的主要作用是方便快速查找,时间复杂度是 O(1),默认大小是 16,数组的下标索引是通过 key 的 hashcode 计算出来的,数组元素叫做 Node,当多个 key 的 hashcode 一致,但 key 值不同时,单个 Node 就会转化成链表,链表的查询复杂度是 O(n),当链表的长度大于等于 8 并且数组的大小超过 64 时,链表就会转化成红黑树,红黑树的查询复杂度是 O(log(n)),简单来说,最坏的查询次数相当于红黑树的最大深度。 1.2 HashMap、TreeMap、LinkedHashMap 三者有啥相同点,有啥不同点? 答:相同点: 三者在特定的情况下,都会使用红黑树; 底层的 hash 算法相同; 在迭代的过程中,如果 Map 的数据结构被改动,都会报 ConcurrentModificationException 的错误。 不同点: HashMap 数据结构以数组为主,查询非常快,TreeMap 数据结构以红黑树为主,利用了红黑树左小右大的特点,可以实现 key 的排序,LinkedHashMap 在 HashMap 的基础上增加了链表的结构,实现了插入顺序访问和最少访问删除两种策略; 由于三种 Map

深入理解JDK8 HashMap

岁酱吖の 提交于 2020-02-18 08:36:18
笔者在上一篇文章《 深入理解JDK7 HashMap 》中详细解析了HashMap在JDK7中的实现原理,主要是围绕其put、get、resize、transfer等方法,本文将继续解析HashMap在JDK8中的具体实现,首先也将从put、get、resize等方法出发,着重解析HashMap在JDK7和JDK8中的具体区别,最后回答并解析一些常见的HashMap问题。在阅读本篇文章之前,建议阅读上一篇文章作为基础。 一、HashMap在JDK8中的结构 上一篇文章提到,HashMap在JDK7或者JDK8中采用的基本存储结构都是 数组+链表 形式,可能有人会提出疑问,HashMap在JDK8中不是 数组+链表+红黑树 吗?本文的回答 是 。至于为什么JDK8在一定条件下将链表转换为红黑树,我相信很多人都会回答: 为了提高查询效率 。基本答案可以说是这样的,JDK7中的HashMap对着Entry节点增多,哈希碰撞的概率在慢慢变大,这就直接导致哈希表中的单链表越来越长,这就大大降低了HashMap的查询能力,且时间复杂度可能会退化到O(n)。针对这种情况,JDK8做出了优化,就是在一定的条件下,链表会被转换为红黑树,提升查询效率。 HashMap在JDK8中基本结构示意图如下所示: 在上面的示意图可以看出,与JDK7的最大区别就是哈希表中不仅有链表,还有可能存在红黑树这种结构

Tree

两盒软妹~` 提交于 2020-02-17 12:29:55
Tree 星星为什么这么渺小?那是因为他们把自己放的太高了! 背景 :简单了解二叉树、平衡树、红黑树、B树和B+树之间的特点和差异。 1. 二叉排序树的特点 a、树的左边节点比根节点小,右边节点比根节点大; b、左右子树也都是二叉排序树; c、但是,在一些特殊情况下,比如插入数据是有序的,就会发生退化情况,如有序序列,即二叉排序树退化成链表。 图1. 二叉树 2. 平衡树 图2. 红黑树 1、为了保证树的平衡,引入了平衡树。在插入数据的时候,同时调整这棵树,让它的节点尽可能均匀分布; 2、红黑树就是平衡树的一种,jdk内置的TreeSet底层就是用的红黑树; 3、之所以要保证树的平衡性,是因为树的查找性能取决于树的高度,让树尽可能平衡,就是为了降低树的高度。 3. B树 a、B树是一种多路搜索树,他的每个节点可以拥有多余两个孩子节点,M路的B树最多能拥有M个孩子节点; b、这种多路的设计,可以进一步降低树的高度。路数越多,树的高度越低。如果设计成无限多路,B树就退化成有序数组了; c、B树一般用于文件系统索引,文件系统和数据库索引一般都存储在硬盘上的,如果数据量大的话,不一定能一次性加载到内存中;如果一棵树无法一次性加载进内存,这时候B树的多路存储能力就出来了,可以每次加载B树的一个节点,然后一步步往下找;如果在内存中,红黑树比B树效率更高,但是涉及到磁盘操作,B树就更优了。 图3

[C++ 系列] 80. 基于4阶B树详解R-BTree红黑树

狂风中的少年 提交于 2020-02-14 00:38:39
文章目录 0. 前言 1. 红黑树的概念 1.1 疑问:红黑树如何保持平衡呢? 1.2 常见的红黑树 2. 红黑树的构成性质 2.1 红黑树的5条重要性质 2.2 请问下面这棵树是 红黑树 吗? 3. 红黑树与4阶B树的关系 3.1 红黑树与4阶B树的等价变换 3.2 红黑树 VS 2-3-4树 4. 相关英文单词 5. 红黑树的添加 5.1 添加前准备 5.2 添加的所有情况 5.3 修复性质4--LL\RR 5.4 修复性质4--LR\RL 5.5 如何区分其它的四种情况 5.6 修复性质4 – 上溢 – LL 5.7 修复性质4 – 上溢 – RR 5.8 修复性质4 – 上溢 – LR 5.9 修复性质4 – 上溢 – RL 6. 红黑树添加元素总结 7. 红黑树的删除 7.1 删除 – RED节点 7.2 删除 – BLACK节点 7.3 删除 – 拥有1个RED子节点的BLACK节点 7.4 删除 – BLACK叶子节点 – sibling(兄弟节点)为BLACK,且有 RED 子节点 7.5 删除 – BLACK叶子节点 – sibling(兄弟节点)为BLACK,没有 RED 子节点 7.6 删除 – BLACK叶子节点 – sibling(兄弟节点)为RED 8. 红黑树删除元素总结 9. 答疑:红黑树的平衡 10. 平均时间复杂度 11. AVL树 vs 红黑树