算法2026-04-15·9 分钟
算法知识库:红黑树实现
红黑树的节点、插入和平衡操作的 JavaScript/TypeScript 实现。
红黑树实现
1. 红黑树基础
- 每个节点要么是红色,要么是黑色。
- 根节点必须是黑色。
- 红色节点的子节点必须是黑色。
- 从根到叶子的每条路径必须包含相同数量的黑色节点。
2. 红黑树节点定义
ts
enum Color {
RED = 'RED',
BLACK = 'BLACK',
}
class RBTreeNode<T = number> {
value: T;
color: Color;
left: RBTreeNode<T> | null = null;
right: RBTreeNode<T> | null = null;
parent: RBTreeNode<T> | null = null;
constructor(value: T, color: Color = Color.RED) {
this.value = value;
this.color = color;
}
}3. 左旋和右旋
ts
function rotateLeft<T>(root: RBTreeNode<T> | null, node: RBTreeNode<T>): RBTreeNode<T> | null {
// 时间复杂度: O(1)
const right = node.right;
if (!right) return root;
node.right = right.left;
if (right.left) right.left.parent = node;
right.parent = node.parent;
if (!node.parent) {
root = right;
} else if (node === node.parent.left) {
node.parent.left = right;
} else {
node.parent.right = right;
}
right.left = node;
node.parent = right;
return root;
}
function rotateRight<T>(root: RBTreeNode<T> | null, node: RBTreeNode<T>): RBTreeNode<T> | null {
// 时间复杂度: O(1)
const left = node.left;
if (!left) return root;
node.left = left.right;
if (left.right) left.right.parent = node;
left.parent = node.parent;
if (!node.parent) {
root = left;
} else if (node === node.parent.right) {
node.parent.right = left;
} else {
node.parent.left = left;
}
left.right = node;
node.parent = left;
return root;
}4. 插入与修复
ts
function insertRB<T>(root: RBTreeNode<T> | null, value: T): RBTreeNode<T> {
// 时间复杂度: O(log n)
const newNode = new RBTreeNode(value);
if (!root) {
newNode.color = Color.BLACK;
return newNode;
}
let parent: RBTreeNode<T> | null = null;
let current = root;
while (current) {
parent = current;
current = value < current.value ? current.left : current.right;
}
newNode.parent = parent;
if (parent) {
if (value < parent.value) parent.left = newNode;
else parent.right = newNode;
}
return insertFixup(root, newNode);
}
function insertFixup<T>(root: RBTreeNode<T>, node: RBTreeNode<T>): RBTreeNode<T> {
// 时间复杂度: O(log n)
while (node.parent && node.parent.color === Color.RED) {
const parent = node.parent;
const grandparent = parent.parent;
if (!grandparent) break;
const uncle = parent === grandparent.left ? grandparent.right : grandparent.left;
if (uncle?.color === Color.RED) {
parent.color = Color.BLACK;
uncle.color = Color.BLACK;
grandparent.color = Color.RED;
node = grandparent;
} else {
if (parent === grandparent.left) {
if (node === parent.right) {
node = parent;
root = rotateLeft(root, node)!;
}
parent.color = Color.BLACK;
grandparent.color = Color.RED;
root = rotateRight(root, grandparent)!;
} else {
if (node === parent.left) {
node = parent;
root = rotateRight(root, node)!;
}
parent.color = Color.BLACK;
grandparent.color = Color.RED;
root = rotateLeft(root, grandparent)!;
}
}
}
root.color = Color.BLACK;
return root;
}5. 实现要点
- 尽量保持 null 节点简化逻辑。
- 旋转时必须同步更新父节点指针。
- 插入后修复时分为颜色重绘和旋转两类操作。
- 红黑树适合实现有序集合、映射和自平衡二叉树。
算法红黑树JavaScript