红黑树用途
- C++中的map,封装了红黑树的实现
- nginx那些点用到了红黑树(nginx timer事件管理)
- 定时器的实现,如何使用红黑树
- cfs进程管理(linux进程调度)
- 内存管理
- Epoll事件块管理
红黑树的性质
- 每个节点都是红的或黑的(红、黑是对节点的一种表述,称1、0树也可以)
- 根节点是黑色的
- 每个叶子节点是黑色的
- 如果一个节点是红色的,则它的两个子节点都是黑色的
- 对于每个节点,从该节点到其子孙的所有路径上包含的黑节点数目都相同![在这里插入图片描述]
如图所示,4张二叉树均有叶子节点省略,1黑色节点的高度不一致,2符合红黑树性质,3黑色节点高度不一致,4红色节点子节点有不为黑的情况。
红黑树的节点表示
typedef int KEY_TYPE;
typedef struct _rbtree_node {
unsigned char color; // 节点颜色
struct _rbtree_node *left;
struct _rbtree_node *right;
struct _rbtree_node *parent; // 指向父节点,旋转时用到
KEY_TYPE key;
void *value;
} rbtree_node;
typedef struct _rbtree {
rbtree_node *root; // 红黑树根节点
rbtree_node *nil; // 红黑树叶子节点,所有叶子节点都指向nil,方便做判断
}
左旋与右旋
左旋
如图所示,x节点进行左旋,x的右子树指向b,y的父节点指向x的父节点,x的父节点指向y
void _left_ratate(rbtree *T, rbtree_node y) {
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 = x;
}
y->left = x;
x->parent = y;
}
右旋
如图所示,y节点进行右旋,y的左子树指向b,x的父节点指向y的父节点,y的父节点指向x
void _right_ratate(rbtree *T, rbtree_node *y) {
rbtree_node *x = y->left;
y->left = x->rigth;
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->left) {
y->parent->left = x;
} else {
y->parent->right = x;
}
x->right= y;
y->parent = x;
}