您的位置:首页 > 理论基础 > 数据结构算法

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

2011-10-26 09:14 288 查看

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的父亲节点

}


(未完待续。。。)




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: