1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-20 22:17:09 +08:00
2023-10-29 10:54:25 +08:00

90 lines
2.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
category: 计算机基础
tag:
- 数据结构
---
# 红黑树
## 红黑树数据结构
建立在 BST 二叉搜索树的基础上AVL、2-3树、红黑树都是自平衡二叉树统称B-树。但相比于AVL树高度平衡所带来的时间复杂度红黑树对平衡的控制要宽松一些红黑树只需要保证黑色节点平衡即可。
## **红黑树特点**
1. 每个节点非红即黑;
黑色决定平衡红色不决定平衡。这对应了2-3树中一个节点内可以存放1~2个节点。
2. 根节点总是黑色的;
3. 每个叶子节点都是黑色的空节点NIL 节点);
这里指的是红黑树都会有一个空的叶子节点,是红黑树自己的规则。
4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
通常这条规则也叫不会有连续的红色节点。一个节点最多临时会有3个节点中间是黑色节点左右是红色节点。
5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。
每一层都只是有一个节点贡献了树高决定平衡性,也就是对应红黑树中的黑色节点。
## 红黑树结构实现
```java
public class Node {
public Class<?> clazz;
public Integer value;
public Node parent;
public Node left;
public Node right;
// AVL 树所需属性
public int height;
// 红黑树所需属性
public Color color = Color.RED;
}
```
### 1.左倾染色
![幻灯片1](pictures/红黑树/红黑树1.PNG)
- 染色时根据当前节点的爷爷节点,找到当前节点的叔叔节点。
- 再把父节点染黑、叔叔节点染黑,爷爷节点染红。但爷爷节点染红是临时的,当平衡树高操作后会把根节点染黑。
### 2.右倾染色
![幻灯片2](pictures/红黑树/红黑树2.PNG)
### 3.左旋调衡
#### 3.1一次左旋
![幻灯片3](pictures/红黑树/红黑树3.PNG)
#### 3.2右旋+左旋
![幻灯片4](pictures/红黑树/红黑树4.PNG)
### 4.右旋调衡
#### 4.1一次右旋
![幻灯片5](pictures/红黑树/红黑树5.PNG)
#### 4.2左旋+右旋
![幻灯片6](pictures/红黑树/红黑树6.PNG)
**红黑树的应用**TreeMap、TreeSet 以及 JDK1.8 的 HashMap 底层都用到了红黑树。
**为什么要用红黑树?** 简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。详细了解可以查看 [漫画:什么是红黑树?](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐)
**相关阅读**[《红黑树深入剖析及 Java 实现》](https://zhuanlan.zhihu.com/p/24367771)(美团点评技术团队)
<!-- @include: @article-footer.snippet.md -->