HashMap中对红黑树、CAS等知识的补充

目录

      • 一、红黑树
        • 1. 概念
        • 2. 图示
        • 3.红黑树的特性
      • 二、 解决哈希冲突常见方法
        • 1. 开放定址法
        • 2. 链接地址
        • 3. 再哈希法
        • 4. 建立公共溢出区
      • 三、CAS
        • 1. 定义
        • 2. 操作
        • 3. Java中CAS操作
        • 4. 存在的问题
        • 5. 实际应用


一、红黑树

1. 概念

是一种自平衡二叉查找树,它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的:它可以在 O(logn)时间内做查找,插入和删除,这里的 {\displaystyle n} n是树中元素的数目。

2. 图示

HashMap中对红黑树、CAS等知识的补充_第1张图片

3.红黑树的特性

(1) 每个节点或者是黑色,或者是红色。
(2) 根节点是黑色。
(3) 每个叶子节点是黑色。 [注意:这里叶子节点,是指为空的叶子节点!]
(4) 如果一个节点是红色的,则它的子节点必须是黑色的。
(5) 从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。

关于它的特性,需要注意的是:
第一,特性(3)中的叶子节点,是只为空(NIL或null)的节点。
第二,特性(5),确保没有一条路径会比其他路径长出俩倍。因而,红黑树是相对是接近平衡的二叉树。

二、 解决哈希冲突常见方法

1. 开放定址法

1)概念
从发生冲突的那个单元起,按照一定的次序,从哈希表中找到一个空闲单元。然后把发生冲突的元素存入到该单元的一种方法
2)线性探测法
线性再散列法是形式最简单的处理冲突的方法:
插入元素时,如果发生冲突,算法会简单的从该槽位置向后循环遍历hash表,直到找到表中的下一个空槽,并将该元素放入该槽中,会导致相同hash值的元素挨在一起和其他hash值对应的槽被占用。

缺点:
①处理溢出需另编程序。一般可另外设立一个溢出表,专门用来存放上述哈希表中放不下的记录。
此溢出表最简单的结构是顺序表,查找方法可用顺序查找
②按上述算法建立起来的哈希表,删除工作非常困难。如果将此元素删除,查找的时会发现空槽,则会认为要找的元素不存在。
只能标上已被删除的标记(逻辑删),否则,将会影响以后的查找。
③线性探测法很容易产生堆聚现象。所谓堆聚现象,就是存入哈希表的记录在表中连成一片。

3)线性补偿探测法
将线性探测的步长从 1 改为 Q
将线性探测的步长从常数改为随机数

4)伪随机探测

2. 链接地址

链接地址法的思路是将哈希值相同的元素构成一个同义词的单链表,并将单链表的头指针存放在哈希表的第i个单元中。

3. 再哈希法

就是同时构造多个不同的哈希函数:
当H1函数发生冲突时,再用H2函数再次进行哈希计算,直到冲突不再产生,这种方法不易产生聚集,但是增加了计算时间。

4. 建立公共溢出区

将哈希表分为公共表和溢出表,当溢出发生时,将所有溢出数据统一放到溢出区。

三、CAS

1. 定义

Compare And Swap(CAS) 简单的说就是比较并交换。

2. 操作

CAS 操作包含三个操作数:
内存位置(V)、预期原值(A)和新值(B),如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值。

3. Java中CAS操作

Java中具体的CAS操作类sun.misc.Unsafe的compareAndSwapXXX方法实现的
HashMap中对红黑树、CAS等知识的补充_第2张图片

4. 存在的问题

1)cpu开销
2)只能保证一个共享变量原子操作 — AtomicReference
3)ABA — 标志位 时间戳

5. 实际应用

1)并发包
2)并发修改
3)底层源码


如果有收获!!! 希望老铁们来个三连,点赞、收藏、转发
创作不易,别忘点个赞,可以让更多的人看到这篇文章,顺便鼓励我写出更好的博客

你可能感兴趣的:(#,Java)