红黑树、HashMap

  1. 红黑数定义:

  2. 满足下列条件的二叉搜索树是红黑树  
  3.   
  4.     * 每个结点要么是“红色”,要么是“黑色”(后面将说明)  
  5.     * 所有的叶结点都是空结点,并且是“黑色”的  
  6.     * 如果一个结点是“红色”的,那么它的两个子结点都是“黑色”的  
  7.     * (注:也就是說,如果結點是黑色的,那么它的子節點可以是紅色或者是黑色的)。  
  8.     * 结点到其子孙结点的每条简单路径都包含相同数目的“黑色”结点  
  9.     * 根结点永远是“黑色”的  
  10.   
  11. 之所以称为红黑树的原因就在于它的每个结点都被“着色”为红色或黑色。这些结点颜色被用来检测树的平衡性。但需要注意的是,红黑树并不是平衡二叉树,恰恰相反,红黑树放松了平衡二叉树的某些要求,由于一定限度的“不平衡”,红黑树的性能得到了提升。 
  12. 平衡二叉树定义:满足根节点的左右子树的深度差的绝对值不超过1的二叉树就是平衡二叉树。 


传统 HashMap 的缺点

JDK 1.8 以前 HashMap 的实现是 数组+链表,即使哈希函数取得再好,也很难达到元素百分百均匀分布。

当 HashMap 中有大量的元素都存放到同一个桶中时,这个桶下有一条长长的链表,这个时候 HashMap 就相当于一个单链表,假如单链表有 n 个元素,遍历的时间复杂度就是 O(n),完全失去了它的优势。

针对这种情况,JDK 1.8 中引入了 红黑树(查找时间复杂度为 O(logn))来优化这个问题。

HashMap 在 JDK 1.8 中新增的数据结构 – 红黑树


  1. 红黑树引入了“颜色”的概念。引入“颜色”的目的在于使得红黑树的平衡条件得以简化。正如著名的密码学专家Bruce Schneier所说的那样,“Being Partly balanced can be good enough”,红黑树并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。  
  2.   
  3. 红黑树能够以O(log2 n)的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。  
  4.   
  5. 当然,红黑树并不适应所有应用树的领域。如果数据基本上是静态的,那么让他们待在他们能够插入,并且不影响平衡的地方会具有更好的性能。如果数据完全是静态的,例如,做一个哈希表,性能可能会更好一些。  
  6.   
  7. 在实际的系统中,例如,需要使用动态规则的防火墙系统,使用红黑树而不是散列表被实践证明具有更好的伸缩性。 





### 三、Java HashMap红黑树的实现原理 在 JDK 1.8 中,`HashMap` 引入了红黑树来优化哈希冲突时的性能表现。当某个桶(bucket)中的链表长度超过 8 个节点时,链表会转换为红黑树结构,从而将查找时间从 O(n) 降低到 O(log n),提升了查找效率[^1]。 #### 1. 红黑树节点结构 红黑树在 `HashMap` 中是通过内部类 `TreeNode` 实现的,它继承自 `LinkedHashMap.Entry`,具有以下关键属性: ```java static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> { TreeNode<K,V> parent; // 指向父节点 TreeNode<K,V> left; // 左孩子节点 TreeNode<K,V> right; // 右孩子节点 TreeNode<K,V> prev; // 前驱节点,用于删除操作 boolean red; // 标记节点颜色,true 表示红色,false 表示黑色 } ``` 这种结构支持红黑树的旋转、变色等操作,使得树在插入或删除节点后仍能维持平衡[^2]。 #### 2. 红黑树的性质 红黑树是一种自平衡的二叉搜索树,具有以下特性: - 每个节点要么是红色,要么是黑色。 - 根节点是黑色。 - 所有叶子节点(NIL 节点)是黑色。 - 如果一个节点是红色,则它的两个子节点必须是黑色。 - 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 这些性质确保了红黑树的近似平衡性,从而保证了查找、插入和删除操作的时间复杂度为 O(log n)[^3]。 #### 3. 插入与平衡调整 在插入新节点时,默认将新节点标记为红色。插入后可能破坏红黑树的性质,需要通过旋转和变色操作进行调整: - 如果父节点是黑色,无需调整。 - 如果父节点是红色,则需要根据叔叔节点的颜色和位置进行变色或旋转操作。 旋转操作包括左旋和右旋,变色操作则用于调整路径上的黑色节点数量[^3]。 #### 4. 链表转红黑树的过程 当链表长度超过阈值(默认为 8)时,链表会转换为红黑树结构。这一过程称为“链表转树”。转换时,链表节点会被重新组织为树节点,并通过 `treeify` 方法完成树结构的构建。树节点之间通过 `left`、`right` 和 `parent` 指针连接,同时保留 `next` 指针用于链表遍历[^4]。 #### 5. 删除与平衡调整 删除操作与插入类似,也可能破坏红黑树的性质。删除节点后,如果被删除节点是黑色,需要通过旋转和变色来重新平衡树结构。这一过程较为复杂,涉及多种情况的判断和处理[^3]。 #### 6. 红黑树退化为链表的情况 当红黑树中某个桶的节点数减少到小于 6 时,红黑树会退化为链表结构。这是为了在节点数量较少时避免树结构带来的额外开销[^1]。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值