一、红黑树定义
红黑树是一种自平衡二叉查找树,它在每个节点上增加了一个存储位来表示节点的颜色,可以是红色或黑色。通过对任何一条从根到叶子节点的路径上各个节点的颜色进行约束,红黑树确保没有一条路径会比其他路径长出两倍,因此,红黑树是近似平衡的。
红黑树的五个性质:
1. 每个节点要么是红色,要么是黑色。
2. 根节点是黑色的。
3. 每个叶子节点(NIL节点,空节点)是黑色的。
4. 如果一个节点是红色的,则它的两个子节点都是黑色的。
5. 对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点。
红黑树的代码实现可以分为以下几个部分:
1. 定义节点结构体
struct Node {
int val;
bool color;
Node *left, *right, *parent;
Node(int val) : val(val), color(RED), left(nullptr), right(nullptr), parent(nullptr) {}
};
```
2. 定义红黑树类
class RedBlackTree {
private:
Node *root;
void leftRotate(Node *x);
void rightRotate(Node *y);
void insertFixup(Node *z);
void transplant(Node *u, Node *v);
void deleteFixup(Node *x);
Node *minimum(Node *x);
public:
RedBlackTree() : root(nullptr) {}
void insert(int val);
void remove(int val);
bool search(int val);
};
3. 实现插入操作
void RedBlackTree::insert(int val) {
Node *z = new Node(val);
Node *y = nullptr;
Node *x = root;
while (x != nullptr) {
y = x;
if (z->val < x->val) {
x = x->left;
} else {
x = x->right;
}
}
z->parent = y;
if (y == nullptr) {
root = z;
} else if (z->val < y->val) {
y->left = z;
} else {
y->right = z;
}
z->left = nullptr;
z->right = nullptr;
z->color = RED;
insertFixup(z);
}
4. 实现插入操作的修复函数
void RedBlackTree::insertFixup(Node *z) {
while (z->parent != nullptr && z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
Node *y = z->parent->parent->right;
if (y != nullptr && y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->right) {
z = z->parent;
leftRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rightRotate(z->parent->parent);
}
} else {
Node *y = z->parent->parent->left;
if (y != nullptr && y->color == RED) {
z->parent->color = BLACK;
y->color = BLACK;
z->parent->parent->color = RED;
z = z->parent->parent;
} else {
if (z == z->parent->left) {
z = z->parent;
rightRotate(z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
leftRotate(z->parent->parent);
}
}
}
root->color = BLACK;
}
5. 实现左旋和右旋操作
void RedBlackTree::leftRotate(Node *x) {
Node *y = x->right;
x->right = y->left;
if (y->left != nullptr) {
y->left->parent = x;
}
y->parent = x->parent;
if (x->parent == nullptr) {
root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
void RedBlackTree::rightRotate(Node *y) {
Node *x = y->left;
y->left = x->right;
if (x->right != nullptr) {
x->right->parent = y;
}
x->parent = y->parent;
if (y->parent == nullptr) {
root = x;
} else if (y == y->parent->left) {
y->parent->left = x;
} else {
y->parent->right = x;
}
x->right = y;
y->parent = x;
}
6. 实现删除操作
void RedBlackTree::remove(int val) {
Node *z = root;
while (z != nullptr) {
if (val == z->val) {
break;
} else if (val < z->val) {
z = z->left;
} else {
z = z->right;
}
}
if (z == nullptr) {
return;
}
Node *x, *y = z;
bool y_original_color = y->color;
if (z->left == nullptr) {
x = z->right;
transplant(z, z->right);
} else if (z->right == nullptr) {
x = z->left;
transplant(z, z->left);
} else {
y = minimum(z->right);
y_original_color = y->color;
x = y->right;
if (y->parent == z) {
x->parent = y;
} else {
transplant(y, y->right);
y->right = z->right;
y->right->parent = y;
}
transplant(z, y);
y->left = z->left;
y->left->parent = y;
y->color = z->color;
}
if (y_original_color == BLACK) {
deleteFixup(x);
}
}
void RedBlackTree::transplant(Node *u, Node *v) {
if (u->parent == nullptr) {
root = v;
} else if (u == u->parent->left) {
u->parent->left = v;
} else {
u->parent->right = v;
}
if (v != nullptr) {
v->parent = u->parent;
}
}
void RedBlackTree::deleteFixup(Node *x) {
while (x != root && x->color == BLACK) {
if (x == x->parent->left) {
Node *w = x->parent->right;
if (w->color == RED) {
w->color = BLACK;
x->parent->color = RED;
leftRotate(x->parent);
w = x->parent->right;
}
if (w->left->color == BLACK && w->right->color == BLACK) {
w->color = RED;
x = x->parent;
} else {
if (w->right->color == BLACK) {
w->left->color = BLACK;
w->color = RED;
rightRotate(w);
w = x->parent->right;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->right->color = BLACK;
leftRotate(x->parent);
x = root;
}
} else {
Node *w = x->parent->left;
if (w->color == RED) {
w->color = BLACK;
x->parent->color = RED;
rightRotate(x->parent);
w = x->parent->left;
}
if (w->right->color == BLACK && w->left->color == BLACK) {
w->color = RED;
x = x->parent;
} else {
if (w->left->color == BLACK) {
w->right->color = BLACK;
w->color = RED;
leftRotate(w);
w = x->parent->left;
}
w->color = x->parent->color;
x->parent->color = BLACK;
w->left->color = BLACK;
rightRotate(x->parent);
x = root;
}
}
}
x->color = BLACK;
}
Node *RedBlackTree::minimum(Node *x) {
while (x->left != nullptr) {
x = x->left;
}
return x;
}