红黑树是什么?红黑树是二叉树,每个节点是由黑和红色组成,红黑树的性质有五条。
1.红黑树的节点颜色由红色与黑色组成
2.根结点都是黑色的
3.两个红色的结点不相邻《不不相邻就是红结点两个子节点都是黑色的》
4.任一节点到叶子,有相同的高度
5.所有的叶子节点都是黑色的
目录;1. 内存管理的红黑树
2. 进程管理的红黑树
3. sk_buff的红黑树
内存管理的红黑树
Linux内存管理模块使用红黑树来提升虚拟内存的查找速度,我们来看看Linux内核目录下的rbtree.c文件:插入,基本就是红黑树的插入节点调整操作
void rb_insert_color(rb_node_t * node, rb_root_t * root)
{
rb_node_t * parent, * gparent;//一个父节点一个祖父节点
//只有当父节点为红色的时候才需要调整
while ((parent = node->rb_parent) && parent->rb_color == RB_RED)
{
gparent = parent->rb_parent;
//如果父节点是爷爷的左子节点,就去判断叔叔节点,是红色就变色操作,否则就进行旋转操作
if (parent == gparent->rb_left)
{
{
register rb_node_t * uncle = gparent->rb_right;
if (uncle && uncle->rb_color == RB_RED)
{
uncle->rb_color = RB_BLACK;
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
node = gparent;
continue;
}
}
if (parent->rb_right == node)
{
register rb_node_t * tmp;
__rb_rotate_left(parent, root);
tmp = parent;
parent = node;
node = tmp;
}
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
__rb_rotate_right(gparent, root);
} else {//当父节点是右子节点的时候就反过来即可
{
register rb_node_t * uncle = gparent->rb_left;
if (uncle && uncle->rb_color == RB_RED)
{
uncle->rb_color = RB_BLACK;
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
node = gparent;
continue;
}
}
if (parent->rb_left == node)
{
register rb_node_t * tmp;
__rb_rotate_right(parent, root);
tmp = parent;
parent = node;
node = tmp;
}
parent->rb_color = RB_BLACK;
gparent->rb_color = RB_RED;
__rb_rotate_left(gparent, root);
}
//最后把根节点颜色改变一下,保证性质一
root->rb_node->rb_color = RB_BLACK;
}
void rb_erase(rb_node_t * node, rb_root_t * root)
{
rb_node_t * child, * parent;
int color;
if (!node->rb_left)
child = node->rb_right;
else if (!node->rb_right)
child = node->rb_left;
else
{
rb_node_t * old = node, * left;
node = node->rb_right;
while ((left = node->rb_left))
node = left;
child = node->rb_right;
parent = node->rb_parent;
color = node->rb_color;
if (child)
child->rb_parent = parent;
if (parent)
{
if (parent->rb_left == node)
parent->rb_left = child;
else
parent->rb_right = child;
}
else
root->rb_node = child;
if (node->rb_parent == old)
parent = node;
node->rb_parent = old->rb_parent;
node->rb_color = old->rb_color;
node->rb_right = old->rb_right;
node->rb_left = old->rb_left;
if (old->rb_parent)
{
if (old->rb_parent->rb_left == old)
old->rb_parent->rb_left = node;
else
old->rb_parent->rb_right = node;
} else
root->rb_node = node;
old->rb_left->rb_parent = node;
if (old->rb_right)
old->rb_right->rb_parent = node;
goto color;
}
parent = node->rb_parent;
color = node->rb_color;
if (child)
child->rb_parent = parent;
if (parent)
{
if (parent->rb_left == node)
parent->rb_left = child;
else
parent->rb_right = child;
}
else
root->rb_node = child;
color:
if (color == RB_BLACK)
__rb_erase_color(child, parent, root);
总结; 时间问题在这我们就简单一些吧,详细的可以后台私信:资料:一起学习哦
关注+后台私信;资料;两个字可以免费领取 资料内容包括:C/C++,Linux,golang,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK,嵌入式 等。。。