JAVA基础集合框架【四】HashMap之源码分析红黑树-数据结构、查找、左右旋转
文章首发于:clawhub.club
数据结构
红黑树本质上是一颗二叉查找树,所以基本结构和二叉查找树是一样的。
二叉查找树的数据结构:
1 | /** |
有根据红黑树的以下五条性质可知,它比二叉查找树多了一个颜色属性。
- 每个结点要么是红的,要么是黑的。
- 根结点是黑的。
- 每个叶结点(叶结点即指树尾端NIL指针或NULL结点)是黑的。
- 如果一个结点是红的,那么它的俩个儿子都是黑的。
- 对于任一结点而言,其到叶结点树尾端NIL指针的每一条路径都包含相同数目的黑结点。
红黑树的数据结构:
1 | /** |
查找
红黑树的查找操作和二叉查找树是一样的。
当红黑树查找的时候,先与当前节点进行比较:
- 如果相等的话就返回当前节点;
- 如果少于当前节点则继续查找当前节点的左节点;
- 如果大于当前节点则继续查找当前节点的右节点。
直到当前节点指针为空或者查找到对应的节点
Java代码实现:
1 | /** |
旋转
上一篇19-HashMap源码分析之红黑树-旋转文章中,只介绍了红黑树旋转的理论知识,本次补充一下Java代码实现。
左旋转
步骤:
- 通过下降节点a,找到上升节点b。(对a左旋转,即以a为圆心的逆时针旋转,a的右子节点b会上升。)
- a的右节点指向b的左节点。
- 如果b的左节点不为空,则b的左节点的父节点指向a。
- 将b的父节点指向a的父节点。
- 如果a是根节点,则将b变为根节点。
- 如果a是其父节点的左节点,则b成为a父节点的左节点。
- 如果a是其父节点的右节点,则b成为a父节点的右节点。
- b的左节点指向a。
- a的父节点指向b。
Java代码实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/**
* 对节点a左旋转,a会变成其右子节点b的左子节点
*
* @param a 待旋转节点a
*/
private void rotateLeft(Node<T> a) {
//节点为空的时候,返回
if (a == null) {
return;
}
//获取其右子节点b
Node<T> b = a.right;
//节点a的右子节点 指向 b的左节点
a.right = b.left;
//如果b的左节点不为空
if (b.left != null) {
//b的左节点的父节点指向a
b.left.parent = a;
}
//b的父节点指向a的父节点
b.parent = a.parent;
//如果a的父节点为空,则b变为根节点
if (a.parent == null) {
root = b;
} else if (a.parent.left == a) {
//如果a是其父节点的左节点,则a的父节点的左节点指向b
a.parent.left = b;
} else {
//如果a是其父节点的右节点,则a的父节点的右节点指向b
a.parent.right = b;
}
//b的左节点指向a
b.left = a;
//a的父节点指向b
a.parent = b;
}
右旋转
算法逻辑可参考左旋转。理解为主。
Java代码实现:
1 | /** |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 ClawHub的技术分享!