用户空间使用Linux数据结构之红黑树(2)

1.5 RB树的操作

红黑树的最主要特征,在于其颜色满足特定的性质。普通的节点添加,极有可能破坏红黑树的性质,所以在添加红黑树节点时,需要将整个红黑树的颜色进行调整。
在理解插入、删除操作之前要先理解两个函数,即红黑树的左旋和右旋。

左旋和右旋都是为了保证平衡二叉树的性质不变,即是通过左旋和右旋来保证红黑二叉树的第五条性质满足。红黑二叉树的添加跟普通的二叉树的添加类似。不过在添加节点后需要对节点的颜色进行调整,甚至对树的结构进行调整,来满足红黑树的性质。

1.5.1左旋

对照下图可以更好的理解下面的程序。将node设置为pivot,root为根。

//记住设置节点的左右孩子后,还要设置节点的parent


static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)

 {

        -------------------------------------------------------------------------(1)

 struct rb_node *right = node->rb_right;          //取node节点的右节点,right= Y

         struct rb_node *parent =rb_parent(node);   //取node节点的父节点,parent= P

---------------------------------------------------------------------------(2)

         if((node->rb_right = right->rb_left))           //注意是 = 而非==,pivot的右子设置为P的左子即//pivot->rb_right= b

                rb_set_parent(right->rb_left, node); //同时将b->parent设置为pivot

----------------------------------------------------------------------------(3)

         right->rb_left = node;                                   //将pivot设置为Y的左子

 

         rb_set_parent(right, parent);                         //设置Y的parent为P

----------------------------------------------------------------------------(4)

         if (parent)

         {

                 if (node ==parent->rb_left)                   //如果pivot为P的左子

                         parent->rb_left =right; //则P的右子设置为Y

                 else

                         parent->rb_right =right;// 否则P的左子设置为Y

         }

         else

                root->rb_node = right;               //如果P为空,即pivot(node)为根节点,旋转//后,Y变为根

         rb_set_parent(node, right);                            //设置pivot的parent为Y

}



 

1.5.2右旋

对照下图可以更好的理解下面的程序。将node设置为pivot,root为根。

static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)

 {

-----------------------------------------------------------(1)

    struct rb_node *left = node->rb_left;           //取pivot节点的左节点,left= Y

      struct rb_node *parent =rb_parent(node);    //取pivot节点的父节点,parent = P

-----------------------------------------------------------(2)

if((node->rb_left = left->rb_right))        // 如果Y不为空,设置pivot的左子为Y的右子     

           rb_set_parent(left->rb_right,node);//设置c的父亲节点为pivot

-----------------------------------------------------------(3)

         left->rb_right = node;                               //设置Y的右节点为pivot

         rb_set_parent(left,parent);                      //设置Y的父亲节点为P

        -----------------------------------------------------------(4)

         if (parent)

         {

                 if (node ==parent->rb_right) // 旋转,设置pivot的原左节点为P的右孩子

                        parent->rb_right = left;

                 else

                        parent->rb_left = left;

         }

         else

                 root->rb_node =left;

         rb_set_parent(node, left);                         //设置pivot的父亲节点

 }




(未完待续。。。)



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值