红黑树
红黑树基础定义
- 二叉搜索树,每个节点要么是黑节点,要么是红节点
- 每个节点到下面叶子节点的所有路径中,黑色节点的数量都相等
- 红色节点的子节点一定是黑色节点
- 根节点是黑色节点
- 叶子节点全是黑色节点。
其C语言的结构体定义如下
c
typedef struct _rbtree_node {
int key;
void *val;
struct _rbtree_node *parent;
struct _rbtree_node *left;
struct _rbtree_node *right;
char color;
} rbtree_node;
typedef struct _rbtree {
struct _rbtree_node *root;
struct _rbtree_node *nil; // 需要生成一个通用的黑色叶子节点,代表空,避免复杂的边界null处理
} rbtree;
红黑树插入新节点
红黑树左旋和右旋
红黑树的插入操作,需要定义左旋和右旋的操作。

从上图可以看出,左旋和右旋是可逆的操作,且不会改变节点的颜色。
- 左旋代码(只有核心操作代码)
c
void rbtree_left_rotation(rbtree *T, rbtree_node *x)
{
rbtree_node *y = x->right;
// 先把b节点放到x的右节点上
x->right = y->left;
if (y->left != T->nil) {
y->left->parent = x;
}
// 再把y节点接到x的父节点上
if (x->parent == T->nil) { // 此时x为根节点,所以parent是空
T->root = y;
} else if (x->parent-left == x) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->parent = x->parent;
// 再把x放到y的左节点上
x->parent = y;
y->left = x;
}
- 右旋代码(把左旋代码中的x和y对调, left和right对调即可)
c
void rbtree_right_rotation(rbtree *T, rbtree_node *y)
{
rbtree_node *x = y->left;
// 先把b节点放到y的左节点上
y->left = x->right;
if (x->right != T->nil) {
x->right->parent = y;
}
// 再把x节点接到y的父节点上
if (y->parent == T->nil) { // 此时x为根节点,所以parent是空
T->root = x;
} else if (y->parent-right == x) {
y->parent->right = x;
} else {
y->parent->left = x;
}
x->parent = y->parent;
// 再把y放到x的右节点上
y->parent = x;
x->right = y;
}
- 插入代码
c
void rbtree_insert_fixup(rbtree *T, rbtree_node *z)
{
while (z->parent->color == RED) {
if (z->parent == z->parent->parent->left) {
rbtree_node *y = z->parent->parent->right;
if (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;
rbtree_left_rotation(T, z);
}
z->parent->color = BLACK;
z->parent->parent->color= RED;
rbtree_right_rotation(T, z->parent);
}
}
}
}
void rbtree_insert(rbtree *T, rbtree_node *z)
{
rbtree_node *x = T->root;
btree_node *y = T->nil;
while (x != T->nil) {
y = x;
if (z->key < x->key) {
x = x->left;
} else if (z->key > x->key) {
x = x->right;
} else {
return;
}
}
if (y == T->nil) {
T->root = z;
return;
}
if (z->key > y->key) {
y->right = z;
} else {
y->left = z;
}
z->parent = y;
z->color = RED;
rbtree_insert_fixup(T, z);
}