Linux红黑树(三)——插入节点

本文详细解析了Linux内核中红黑树插入节点的过程,包括更换孩子节点、旋转辅助函数以及针对不同情况的插入调整。通过肢解函数和示例,帮助读者理解红黑树插入节点的细节和保持树平衡的重要性。
摘要由CSDN通过智能技术生成

知识温习:

wiki-red-black tree insert node,对插入节点有详细的介绍

wiki-AVL-tree insert rotate, 对平衡二叉树旋转调整

前言

红黑树的5大“纪律”

性质1. 节点是红色或黑色。

性质2. 根是黑色。

性质3. 所有叶子都是黑色(叶子是NIL节点)。

性质4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

性质5. 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。


以上5条,是红黑树“铁”的纪律,任何一条不成立,就不再是一棵红黑树。而红黑树节点的插入会导致原有红黑树中的某些性质不再成立,因此需要对树进行适当的调整(旋转——附带性的改变孩子,改变父亲或者改变颜色)使之依旧是一棵红黑树。下文介绍的就是内核对红黑树插入节点的调整分析!如果对AVL树不了解,树的插入节点不了解,请查看我给予的wiki链接进行温习,否则,你可能会看不明白下文中操作的原因。

1、更换孩子节点

<linux/rbtree_augmented.h>

static inline void
__rb_change_child(struct rb_node *old, struct rb_node *new,
		  struct rb_node *parent, struct rb_root *root)
{
	if (parent) {//parent不空,则不是树根
		if (parent->rb_left == old)//更换是左孩子
			parent->rb_left = new;
		else //更换的是右孩子
			parent->rb_right = new;
	} else //更换树根
		root->rb_node = new;
}

内部函数——只有单一功能实现,不做安全机制,以及高级功能封装,核心一向如此。


2、旋转辅助函数

<lib/rbtree.c>

__rb_rotate_set_parents(struct rb_node *old, struct rb_node *new, struct rb_root *root, int color)
{
//获取old的父节点
        struct rb_node *parent = rb_parent(old);
       
//old's parent and color get assigned to new
        new->__rb_parent_color = old->__rb_parent_color;

//old gets assigned new as a parent and 'color' as a color
        rb_set_parent_color(old, new, color);

//把parent的old孩子替换成new
        __rb_change_child(old, new, parent, root);
}

3、"插入"节点

<lib/rbtree.c>

void rb_insert_color(struct rb_node *node, struct rb_root *root)
{
	__rb_insert(node, root, dummy_rotate);
}
EXPORT_SYMBOL(rb_insert_color);

很显然,这是对外导出使用的外部函数,真正的功能函数是__rb_insert();

一般刚看到代码时候,会觉得困惑,为什么函数名字叫rb_insert_color(),而不是rb_insert_node之类的?

原因在上一篇博客中“核心对红黑树使用两点说明

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值