红黑树C源码实现与剖析
作者:July 、那谁 时间:二零一一年一月三日
-------------------------
前言:
红黑树作为一种经典而高级的数据结构,相信,已经被不少人实现过,但不是因为程序不够完善而无法运行,就是因为程序完全没有注释,初学者根本就看不懂。
此份红黑树的c源码最初从linux-lib-rbtree.c而来,后经一网友那谁(http://www.cppblog.com/converse/)用c写了出来。在此,向原作者表示敬意。但原来的程序存在没有任何一行注释。没有一行注释的程序,令程序的价值大打折扣。
所以,我特把这份源码放到了windows xp+vc 6.0上,一行一行的完善,一行一行的给它添加注释,至此,红黑树c带注释的源码,就摆在了您眼前,有不妥、不正之处,还望不吝指正。
------------
红黑树的六篇文章:
1、教你透彻了解红黑树
2、红黑树算法的实现与剖析
3、红黑树的c源码实现与剖析
4、一步一图一代码,R-B Tree
5、红黑树插入和删除结点的全程演示
6、红黑树的c++完整实现源码
-------------------------
ok,咱们开始吧。
相信,经过我前俩篇博文对红黑树的介绍,你应该对红黑树有了透彻的理解了(没看过的朋友,可事先查上面的倆篇文章,或与此文的源码剖析对应着看)。
本套源码剖析把重点放在红黑树的3种插入情况,与红黑树的4种删除情况。其余的能从略则尽量简略。
目录:
一、左旋代码分析
二、右旋
三、红黑树查找结点
四、红黑树的插入
五、红黑树的3种插入情况
六、红黑树的删除
七、红黑树的4种删除情况
八、测试用例
好的,咱们还是先从树的左旋、右旋代码,开始(大部分分析,直接给注释):
-
-
-
-
-
-
-
-
- static rb_node_t* rb_rotate_left(rb_node_t* node, rb_node_t* root)
- {
- rb_node_t* right = node->right;
-
- if ((node->right = right->left))
- {
- right->left->parent = node;
- }
- right->left = node;
-
- if ((right->parent = node->parent))
- {
- if (node == node->parent->right)
- {
- node->parent->right = right;
- }
- else
- {
- node->parent->left = right;
- }
- }
- else
- {
- root = right;
- }
- node->parent = right;
-
- return root;
- }
-
-
-
-
-
-
-
-
-
-
- static rb_node_t* rb_rotate_right(rb_node_t* node, rb_node_t* root)
- {
- rb_node_t* left = node->left;
-
- if ((node->left = left->right))
- {
- left->right->parent = node;
- }
- left->right = node;
-
- if ((left->parent = node->parent))
- {
- if (node == node->parent->right)
- {
- node->parent->right = left;
- }
- else
- {
- node->parent->left = left;
- }
- }
- else
- {
- root = left;
- }
- node->parent = left;
-
- return root;
- }
-
-
-
-
-
-
-
- static rb_node_t* rb_search_auxiliary(key_t key, rb_node_t* root, rb_node_t** save)
- {
- rb_node_t *node = root, *parent = NULL;
- int ret;
-
- while (node)
- {
- parent = node;
- ret = node->key - key;
- if (0 < ret)
- {
- node = node->left;
- }
- else if (0 > ret)
- {
- node = node->right;
- }
- else
- {
- return node;
- }
- }
-
- if (save)
- {
- *save = parent;
- }
-
- return NULL;
- }
-
-
- rb_node_t* rb_search(key_t key, rb_node_t* root)
- {
- return rb_search_auxiliary(key, root, NULL);
- }
-
-
-
-
-
- rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root)
- {
- rb_node_t *parent = NULL, *node;
-
- parent = NULL;
- if ((node = rb_search_auxiliary(key, root, &parent)))
-
- 点的地方
- {
- return root;
- }
-
- node = rb_new_node(key, data);
- node->parent = parent;
- node->left = node->right = NULL;
- node->color = RED;
-
- if (parent)
- {
- if (parent->key > key)
- {
- parent->left = node;
- }
- else
- {
- parent->right = node;
- }
- }
- else
- {
- root = node;
- }
-
- return rb_insert_rebalance(node, root);
-
- 的性质
- }
-
-
-
-
-
-
-
-
-
- static rb_node_t* rb_insert_rebalance(rb_node_t *node, rb_node_t *root)
- {
- rb_node_t *parent, *gparent, *uncle, *tmp;
-
- while ((parent = node->parent) && parent->color == RED)
- {
- gparent = parent->parent;
-
- if (parent == gparent->left)
-
- {
- uncle = gparent->right;
-
- if (uncle && uncle->color == RED)
- {
- uncle->color = BLACK;
- parent->color = BLACK;
- gparent->color = RED;
- node = gparent;
-
- }
- else
- {
- if (parent->right == node)
- {
- root = rb_rotate_left(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
- }
-
-
-
- parent->color = BLACK;
- gparent->color = RED;
- root = rb_rotate_right(gparent, root);
- }
- }
-
- else
- {
-
- uncle = gparent->left;
- if (uncle && uncle->color == RED)
- {
- uncle->color = BLACK;
- parent->color = BLACK;
- gparent->color = RED;
- node = gparent;
- }
- else
- {
- if (parent->left == node)
- {
- root = rb_rotate_right(parent, root);
- tmp = parent;
- parent = node;
- node = tmp;
- }
-
- parent->color = BLACK;
- gparent->color = RED;
- root = rb_rotate_left(gparent, root);
- }
- }
- }
-
- root->color = BLACK;
- return root;
- }
-
-
-
-
-
- rb_node_t* rb_erase(key_t key, rb_node_t *root)
- {
- rb_node_t *child, *parent, *old, *left, *node;
- color_t color;
-
- if (!(node = rb_search_auxiliary(key, root, NULL)))
-
- 结点
- {
- printf("key %d is not exist!/n");
- return root;
- }
-
- old = node;
-
- if (node->left && node->right)
- {
- node = node->right;
- while ((left = node->left) != NULL)
- {
- node = left;
- }
- child = node->right;
- parent = node->parent;
- color = node->color;
-
- if (child)
- {
- child->parent = parent;
- }
- if (parent)
- {
- if (parent->left == node)
- {
- parent->left = child;
- }
- else
- {
- parent->right = child;
- }
- }
- else
- {
- root = child;
- }
-
- if (node->parent == old)
- {
- parent = node;
- }
-
- node->parent = old->parent;
- node->color = old->color;
- node->right = old->right;
- node->left = old->left;
-
- if (old->parent)
- {
- if (old->parent->left == old)
- {
- old->parent->left = node;
- }
- else
- {
- old->parent->right = node;
- }
- }
- else
- {
- root = node;
- }
-
- old->left->parent = node;
- if (old->right)
- {
- old->right->parent = node;
- }
- }
- else
- {
- if (!node->left)
- {
- child = node->right;
- }
- else if (!node->right)
- {
- child = node->left;
- }
- parent = node->parent;
- color = node->color;
-
- if (child)
- {
- child->parent = parent;
- }
- if (parent)
- {
- if (parent->left == node)
- {
- parent->left = child;
- }
- else
- {
- parent->right = child;
- }
- }
- else
- {
- root = child;
- }
- }
-
- free(old);
-
- if (color == BLACK)
- {
- root = rb_erase_rebalance(child, parent, root);
-
- 质
- }
-
- return root;
- }
-
-
-
-
-
-
-
-
- static rb_node_t* rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root)
- {
- rb_node_t *other, *o_left, *o_right;
-
- while ((!node || node->color == BLACK) && node != root)
- {
- if (parent->left == node)
- {
- other = parent->right;
- if (other->color == RED)
- {
- other->color = BLACK;
- parent->color = RED;
- root = rb_rotate_left(parent, root);
- other = parent->right;
-
- 的效果。
- }
- if ((!other->left || other->left->color == BLACK) &&
- (!other->right || other->right->color == BLACK))
-
-
- 都是黑色的
-
- {
- other->color = RED;
- node = parent;
- parent = node->parent;
- }
- else
- {
- if (!other->right || other->right->color == BLACK)
- {
- if ((o_left = other->left))
- {
- o_left->color = BLACK;
- }
- other->color = RED;
- root = rb_rotate_right(other, root);
- other = parent->right;
-
- w。
- }
-
-
- other->color = parent->color;
- parent->color = BLACK;
- if (other->right)
- {
- other->right->color = BLACK;
- }
- root = rb_rotate_left(parent, root);
- node = root;
- break;
- }
- }
-
- else
- {
- other = parent->left;
- if (other->color == RED)
- {
- other->color = BLACK;
- parent->color = RED;
- root = rb_rotate_right(parent, root);
- other = parent->left;
- }
- if ((!other->left || other->left->color == BLACK) &&
- (!other->right || other->right->color == BLACK))
- {
- other->color = RED;
- node = parent;
- parent = node->parent;
- }
- else
- {
- if (!other->left || other->left->color == BLACK)
- {
- if ((o_right = other->right))
- {
- o_right->color = BLACK;
- }
- other->color = RED;
- root = rb_rotate_left(other, root);
- other = parent->left;
- }
- other->color = parent->color;
- parent->color = BLACK;
- if (other->left)
- {
- other->left->color = BLACK;
- }
- root = rb_rotate_right(parent, root);
- node = root;
- break;
- }
- }
- }
-
- if (node)
- {
- node->color = BLACK;
- }
- return root;
- }
-
-
-
-
- int main()
- {
- int i, count = 100;
- key_t key;
- rb_node_t* root = NULL, *node = NULL;
-
- srand(time(NULL));
- for (i = 1; i < count; ++i)
- {
- key = rand() % count;
- if ((root = rb_insert(key, i, root)))
- {
- printf("[i = %d] insert key %d success!/n", i, key);
- }
- else
- {
- printf("[i = %d] insert key %d error!/n", i, key);
- exit(-1);
- }
-
- if ((node = rb_search(key, root)))
- {
- printf("[i = %d] search key %d success!/n", i, key);
- }
- else
- {
- printf("[i = %d] search key %d error!/n", i, key);
- exit(-1);
- }
- if (!(i % 10))
- {
- if ((root = rb_erase(key, root)))
- {
- printf("[i = %d] erase key %d success/n", i, key);
- }
- else
- {
- printf("[i = %d] erase key %d error/n", i, key);
- }
- }
- }
-
- return 0;
- }
ok,完。
后记:
一、欢迎任何人就此份源码,以及我的前述倆篇文章,进行讨论、提议。
但任何人,引用此份源码剖析,必须得注明作者本人July以及出处。
红黑树系列,已经写了三篇文章,相信,教你透彻了解红黑树的目的,应该达到了。
二、本文完整源码,请到此处下载:
http://download.csdn.net/source/2958890
1、教你透彻了解红黑树
2、红黑树算法的实现与剖析
3、红黑树的c源码实现与剖析
4、一步一图一代码,R-B Tree
5、红黑树插入和删除结点的全程演示
6、红黑树的c++完整实现源码
转载本BLOG内任何文章,请以超链接形式注明出处。非常感谢。