1 红黑树的应用
1.Linux进程调度CFS
2.Nginx Timer事件管理
3.Epoll事件块的管理
2 红黑树概念
- 每个节点都是红的或者是黑色的
- 根节点是黑色的
- 每个叶子节点是黑色的
- 如果一个节点是红色的,则它的两个子节点是黑色的
- 从任意节点到其每个叶子的所有路径都包含相同数量的黑色节点
3 红黑树实现代码(C++)
3.1 红黑树节点实现
typedef int KEY_TYPE;
typedef struct _rbtree_node {
KEY_TYPE key;
void *value;
struct _rbtree_node *right;
struct _rbtree_node *left;
struct _rbtree_node *parent;
unsigned char color;
} rbtree_node;
3.2 红黑树实现
typedef struct _rbtree {
struct _rbtree_node *root;
struct _rbtree_node *nil;
} rbtree;
3.3 左旋和右旋
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/784c6e86db28989709e964b2f8f238c6.png)
3.3.1 左旋代码实现
void rbtree_left_roate(rbtree *T, rbtree_node *x) {
rbtree_node *y = x->right;
x->right = y->left;
if (y->left != T->nil) {
y->left->parent = x;
}
y->parent = x->parent;
if(x->parent == T->nil) {
T->root = y;
} else if (x == x->parent->left) {
x->parent->left = y;
} else {
x->parent->right = y;
}
y->left = x;
x->parent = y;
}
3.3.2右旋代码实现
右旋和左旋类似,具有对称性和可逆性,所以代码可以将x与y互换,left与right互换
void rbtree_right_roate(rbtree *T, rbtree_node *y) {
rbtree_node *x = y->left;
y->left = x->right;
if (x->right != T->nil) {
x->right->parent = y;
}
x->parent = y->parent;
if(y->parent == T->nil) {
T->root = x;
} else if (y == y->parent->right) {
y->parent->right = x;
} else {
y->parent->left = x;
}
x->right = y;
y->parent = x;
}
3.4 插入操作
void rbtree_insert(rbtree *T, rbtree_node *z) {
rbtree_node *y = T->nil;
rbtree_node *x = T->root;
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;
} else {
if(z->key < y->key) {
y->left = z;
} else {
y->right = z;
}
}
z->parent = y;
z->left = T->nil;
z->right = T->nil;
z->color = RED;
rbtree_insert_fixup(T, z);
}
3.5 调整函数
下面的情况4、5、6与1、2、3是对称关系,只需把左旋操作与右旋操作互换即可,具体可以自己将情况1、2、3的图示对称就能形成4、5、6的情况
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_rotate(T, z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rbtree_right_rotate(T, z->parent->parent);
}
} else {
rbtree_node *y = z->parent->parent->left;
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-left) {
z = z->parent;
rbtree_right_rotate(T, z);
}
z->parent->color = BLACK;
z->parent->parent->color = RED;
rbtree_left_rotate(T, z->parent->parent);
}
}
}
}