红黑树介绍与分析(2)

新节点内侧插入情况:先对父节点左单选(如果这里不进行左旋转,则经过下一步的右旋转后,新节点即成为祖父节点的左孩子,如果祖父节点为红色,则会引入额外的调整和麻烦),改变新节点和祖父节点颜色,再对祖父节点右单旋;

叔父节点颜色为红色

红黑树

该情况下比较简单,因为叔父和父节点都是红色,而且祖父节点为黑色,则将祖父节点颜色变为红色,父节点和叔父节点颜色为黑色,即可消除相邻的两个红色节点而且不改变相应的黑高度,此时如果曾祖父节点颜色为黑色,则调整结束,如果曾祖父节点颜色为红色,则可将祖父节点视为新节点,递归新插入情况,迭代向上处理。

红黑树

总体来说插入情况相对比较简单,主要涉及上述几种操作,以下是c语言相关红黑树插入实现代码:

/*

* key:新插入节点键值,root:红黑树根节点

* 红黑树节点插入

* 1、插入新节点

* 2、旋转红黑树并做颜色调整

*/

rb_node_t *rb_tree_insert(int key, rb_node_t* root)

{

rb_node_t *last_node;

rb_node_t *curnode;

/* 创建节点 */

rb_node_t *node = (rb_node_t *)malloc(sizeof(rb_node_t));

node->key = key;

curnode = root; //temp node,just for save something

/* 树为空 */

if (NULL == root)

{

node->color = black;

node->left_child = NULL;

node->right_child = NULL;

node->parent = NULL;

return node;

}

/* 向下搜索,直到找到相应的位置可以插入 */

while (curnode)

{

last_node = curnode;

node->key > curnode->key ? (curnode = curnode->right_child) : (curnode = curnode->left_child);

}

/* 判断插入搜索到的节点的左孩子还是右孩子 */

if (node->key > last_node->key)

last_node->right_child = node;

else

last_node->left_child = node;

node->parent = last_node;        //回马枪设置父节点

node->left_child = NULL;

node->right_child = NULL;

node->color = red;

/* 重新使红黑树调整为平衡状态 */

root = rb_tree_rebalance(node, root);

return root;

}

删除操作:

红黑树节点删除操作后的调整相比插入操作更加复杂,但是同样可以分情况讨论之。

首先红黑树删除同样采取跟二叉搜索树同样的删除方式,即如果需要删除节点A,则将A左子树中最大的节点(即最右边节点)和右子树中最小的节点(最左边的节点)删除,然后用删除节点替换A节点。

如下图:

红黑树

需要删除8节点时,先搜索到7或9节点,将对应节点删除掉,同时将7或9的节点替换8的节点,详细参考请查阅二叉搜索树的删除。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/23488.html