TreeMap底层基于红黑树实现,左旋和右旋是维持其平衡的核心操作;二者不对外暴露,需配合颜色重涂使用,且仅修改指针结构、不改变键值或节点颜色。

TreeMap 底层基于红黑树实现,左旋(left rotate)和右旋(right rotate)是维持红黑树平衡的核心操作。它们不直接对外暴露,但理解其逻辑对掌握 TreeMap 原理至关重要。下面以标准红黑树节点结构为基础,给出清晰、可运行的 Java 实现。
红黑树节点定义(简化版)
为便于演示,先定义一个基础节点类,包含关键字段:
<font size="2">static class Node<K,V> {
K key;
V value;
Node<K,V> left, right, parent;
boolean color; // true 表示红色,false 表示黑色(也可用枚举,此处简化)
Node(K key, V value) {
this.key = key;
this.value = value;
this.color = true; // 新节点默认为红色
}
}</font>
右旋操作(Right Rotate)
右旋以节点 x 为轴,将其左子节点 y 提升为新父节点,x 成为 y 的右子节点。需同步更新父子指针和子树连接。
关键点:
– 旋转前要求 x.left != null
– 旋转后,原 y.right 变成 x.left
– 父节点关系必须双向更新(包括祖父节点的子引用)
<font size="2">void rightRotate(Node<K,V> x) {
Node<K,V> y = x.left; // y 是 x 的左子节点
if (y == null) return;
// 1. 将 y 的右子树挂到 x 的左子位置
x.left = y.right;
if (y.right != null) {
y.right.parent = x;
}
// 2. 将 x 作为 y 的右子节点
y.parent = x.parent;
if (x.parent == null) {
root = y; // x 原来是根,则 y 成为新根
} else if (x == x.parent.right) {
x.parent.right = y;
} else {
x.parent.left = y;
}
// 3. 连接 x 和 y
y.right = x;
x.parent = y;
}</font>
左旋操作(Left Rotate)
左旋是右旋的镜像:以节点 x 为轴,将其右子节点 y 提升为父节点,x 成为 y 的左子节点。
立即学习“Java免费学习笔记(深入)”;
<font size="2">void leftRotate(Node<K,V> x) {
Node<K,V> y = x.right;
if (y == null) return;
x.right = y.left;
if (y.left != null) {
y.left.parent = x;
}
y.parent = x.parent;
if (x.parent == null) {
root = y;
} else if (x == x.parent.left) {
x.parent.left = y;
} else {
x.parent.right = y;
}
y.left = x;
x.parent = y;
}</font>
实际使用中的注意事项
这些旋转操作本身不改变节点颜色,后续需配合颜色重涂(recoloring)完成红黑树修复。在 TreeMap 源码中,旋转被封装在 fixAfterInsert 和 fixAfterDelete 方法内,与颜色调整严格配合。
- 旋转只修改指针结构,不涉及键值比较或数据移动
- 必须确保 parent 字段始终准确,否则会导致树断裂或遍历错误
- 单次旋转不能解决所有失衡,通常需结合变色 + 一次或多次旋转
- Java 8+ 的
TreeMap源码中对应方法名为rotateLeft/rotateRight,逻辑与上述一致


















