免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: converse
打印 上一主题 下一主题

[算法] 红黑树的实现源码(C语言版) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-10 17:40 |显示全部楼层 |倒序浏览
不多说啥了,这里不讲理论, 需要的可以自己去看书(如算法导论等), 就给出一份实现代码, 供有需要的人参考之用, 前后写了好久, 参考的是linux内核中红黑树的实现代码:http://lxr.linux.no/linux/lib/rbtree.c

实现的操作有:插入, 查找, 删除.


  1. /*-----------------------------------------------------------
  2.     RB-Tree的插入和删除操作的实现算法
  3.     参考资料:
  4.     1) <<Introduction to algorithm>>
  5.     2) [url]http://lxr.linux.no/linux/lib/rbtree.c[/url]

  6.     作者:[url]http://www.cppblog.com/converse/[/url]
  7.     您可以自由的传播,修改这份代码,转载处请注明原作者

  8.     红黑树的几个性质:
  9.     1) 每个结点只有红和黑两种颜色
  10.     2) 根结点是黑色的
  11.     3)空节点是黑色的(红黑树中,根节点的parent以及所有叶节点lchild、rchild都不指向NULL,而是指向一个定义好的空节点)。
  12.     4) 如果一个结点是红色的,那么它的左右两个子结点的颜色是黑色的
  13.     5) 对于每个结点而言,从这个结点到叶子结点的任何路径上的黑色结点
  14.     的数目相同
  15. -------------------------------------------------------------*/

  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>

  19. typedef int key_t;
  20. typedef int data_t;

  21. typedef enum color_t
  22. {
  23.     RED = 0,
  24.     BLACK = 1
  25. }color_t;

  26. typedef struct rb_node_t
  27. {
  28.     struct rb_node_t *left, *right, *parent;
  29.     key_t key;
  30.     data_t data;
  31.     color_t color;
  32. }rb_node_t;

  33. /* forward declaration */
  34. rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root);
  35. rb_node_t* rb_search(key_t key, rb_node_t* root);
  36. rb_node_t* rb_erase(key_t key, rb_node_t* root);

  37. int main()
  38. {
  39.     int i, count = 900000;
  40.     key_t key;
  41.     rb_node_t* root = NULL, *node = NULL;
  42.    
  43.     srand(time(NULL));
  44.     for (i = 1; i < count; ++i)
  45.     {
  46.         key = rand() % count;
  47.         if ((root = rb_insert(key, i, root)))
  48.         {
  49.             printf("[i = %d] insert key %d success!\n", i, key);
  50.         }
  51.         else
  52.         {
  53.             printf("[i = %d] insert key %d error!\n", i, key);
  54.             exit(-1);
  55.         }

  56.         if ((node = rb_search(key, root)))
  57.         {
  58.             printf("[i = %d] search key %d success!\n", i, key);
  59.         }
  60.         else
  61.         {
  62.             printf("[i = %d] search key %d error!\n", i, key);
  63.             exit(-1);
  64.         }
  65.         if (!(i % 10))
  66.         {
  67.             if ((root = rb_erase(key, root)))
  68.             {
  69.                 printf("[i = %d] erase key %d success\n", i, key);
  70.             }
  71.             else
  72.             {
  73.                 printf("[i = %d] erase key %d error\n", i, key);
  74.             }
  75.         }
  76.     }

  77.     return 0;
  78. }

  79. static rb_node_t* rb_new_node(key_t key, data_t data)
  80. {
  81.     rb_node_t *node = (rb_node_t*)malloc(sizeof(struct rb_node_t));

  82.     if (!node)
  83.     {
  84.         printf("malloc error!\n");
  85.         exit(-1);
  86.     }
  87.     node->key = key, node->data = data;

  88.     return node;
  89. }

  90. /*-----------------------------------------------------------
  91. |   node           right
  92. |   / \    ==>     / \
  93. |   a  right     node  y
  94. |       / \           / \
  95. |       b  y         a   b
  96. -----------------------------------------------------------*/
  97. static rb_node_t* rb_rotate_left(rb_node_t* node, rb_node_t* root)
  98. {
  99.     rb_node_t* right = node->right;

  100.     if ((node->right = right->left))
  101.     {
  102.         right->left->parent = node;
  103.     }
  104.     right->left = node;

  105.     if ((right->parent = node->parent))
  106.     {
  107.         if (node == node->parent->right)
  108.         {
  109.             node->parent->right = right;
  110.         }
  111.         else
  112.         {
  113.             node->parent->left = right;
  114.         }
  115.     }
  116.     else
  117.     {
  118.         root = right;
  119.     }
  120.     node->parent = right;

  121.     return root;
  122. }

  123. /*-----------------------------------------------------------
  124. |       node           left
  125. |       / \            / \
  126. |    left  y   ==>    a   node
  127. |   / \               / \
  128. |  a   b             b   y
  129. -----------------------------------------------------------*/
  130. static rb_node_t* rb_rotate_right(rb_node_t* node, rb_node_t* root)
  131. {
  132.     rb_node_t* left = node->left;

  133.     if ((node->left = left->right))
  134.     {
  135.         left->right->parent = node;
  136.     }
  137.     left->right = node;

  138.     if ((left->parent = node->parent))
  139.     {
  140.         if (node == node->parent->right)
  141.         {
  142.             node->parent->right = left;
  143.         }
  144.         else
  145.         {
  146.             node->parent->left = left;
  147.         }
  148.     }
  149.     else
  150.     {
  151.         root = left;
  152.     }
  153.     node->parent = left;

  154.     return root;
  155. }

  156. static rb_node_t* rb_insert_rebalance(rb_node_t *node, rb_node_t *root)
  157. {
  158.     rb_node_t *parent, *gparent, *uncle, *tmp;

  159.     while ((parent = node->parent) && parent->color == RED)
  160.     {
  161.         gparent = parent->parent;

  162.         if (parent == gparent->left)
  163.         {
  164.             uncle = gparent->right;
  165.             if (uncle && uncle->color == RED)
  166.             {
  167.                 uncle->color = BLACK;
  168.                 parent->color = BLACK;
  169.                 gparent->color = RED;
  170.                 node = gparent;
  171.             }
  172.             else
  173.             {
  174.                 if (parent->right == node)
  175.                 {
  176.                     root = rb_rotate_left(parent, root);
  177.                     tmp = parent;
  178.                     parent = node;
  179.                     node = tmp;
  180.                 }

  181.                 parent->color = BLACK;
  182.                 gparent->color = RED;
  183.                 root = rb_rotate_right(gparent, root);
  184.             }
  185.         }
  186.         else
  187.         {
  188.             uncle = gparent->left;
  189.             if (uncle && uncle->color == RED)
  190.             {
  191.                 uncle->color = BLACK;
  192.                 parent->color = BLACK;
  193.                 gparent->color = RED;
  194.                 node = gparent;
  195.             }
  196.             else
  197.             {
  198.                 if (parent->left == node)
  199.                 {
  200.                     root = rb_rotate_right(parent, root);
  201.                     tmp = parent;
  202.                     parent = node;
  203.                     node = tmp;
  204.                 }

  205.                 parent->color = BLACK;
  206.                 gparent->color = RED;
  207.                 root = rb_rotate_left(gparent, root);
  208.             }
  209.         }
  210.     }

  211.     root->color = BLACK;

  212.     return root;
  213. }

  214. static rb_node_t* rb_erase_rebalance(rb_node_t *node, rb_node_t *parent, rb_node_t *root)
  215. {
  216.     rb_node_t *other, *o_left, *o_right;

  217.     while ((!node || node->color == BLACK) && node != root)
  218.     {
  219.         if (parent->left == node)
  220.         {
  221.             other = parent->right;
  222.             if (other->color == RED)
  223.             {
  224.                 other->color = BLACK;
  225.                 parent->color = RED;
  226.                 root = rb_rotate_left(parent, root);
  227.                 other = parent->right;
  228.             }
  229.             if ((!other->left || other->left->color == BLACK) &&
  230.                 (!other->right || other->right->color == BLACK))
  231.             {
  232.                 other->color = RED;
  233.                 node = parent;
  234.                 parent = node->parent;
  235.             }
  236.             else
  237.             {
  238.                 if (!other->right || other->right->color == BLACK)
  239.                 {
  240.                     if ((o_left = other->left))
  241.                     {
  242.                         o_left->color = BLACK;
  243.                     }
  244.                     other->color = RED;
  245.                     root = rb_rotate_right(other, root);
  246.                     other = parent->right;
  247.                 }
  248.                 other->color = parent->color;
  249.                 parent->color = BLACK;
  250.                 if (other->right)
  251.                 {
  252.                     other->right->color = BLACK;
  253.                 }
  254.                 root = rb_rotate_left(parent, root);
  255.                 node = root;
  256.                 break;
  257.             }
  258.         }
  259.         else
  260.         {
  261.             other = parent->left;
  262.             if (other->color == RED)
  263.             {
  264.                 other->color = BLACK;
  265.                 parent->color = RED;
  266.                 root = rb_rotate_right(parent, root);
  267.                 other = parent->left;
  268.             }
  269.             if ((!other->left || other->left->color == BLACK) &&
  270.                 (!other->right || other->right->color == BLACK))
  271.             {
  272.                 other->color = RED;
  273.                 node = parent;
  274.                 parent = node->parent;
  275.             }
  276.             else
  277.             {
  278.                 if (!other->left || other->left->color == BLACK)
  279.                 {
  280.                     if ((o_right = other->right))
  281.                     {
  282.                         o_right->color = BLACK;
  283.                     }
  284.                     other->color = RED;
  285.                     root = rb_rotate_left(other, root);
  286.                     other = parent->left;
  287.                 }
  288.                 other->color = parent->color;
  289.                 parent->color = BLACK;
  290.                 if (other->left)
  291.                 {
  292.                     other->left->color = BLACK;
  293.                 }
  294.                 root = rb_rotate_right(parent, root);
  295.                 node = root;
  296.                 break;
  297.             }
  298.         }
  299.     }

  300.     if (node)
  301.     {
  302.         node->color = BLACK;
  303.     }

  304.     return root;
  305. }

  306. static rb_node_t* rb_search_auxiliary(key_t key, rb_node_t* root, rb_node_t** save)
  307. {
  308.     rb_node_t *node = root, *parent = NULL;
  309.     int ret;

  310.     while (node)
  311.     {
  312.         parent = node;
  313.         ret = node->key - key;
  314.         if (0 < ret)
  315.         {
  316.             node = node->left;
  317.         }
  318.         else if (0 > ret)
  319.         {
  320.             node = node->right;
  321.         }
  322.         else
  323.         {
  324.             return node;
  325.         }
  326.     }

  327.     if (save)
  328.     {
  329.         *save = parent;
  330.     }

  331.     return NULL;
  332. }

  333. rb_node_t* rb_insert(key_t key, data_t data, rb_node_t* root)
  334. {
  335.     rb_node_t *parent = NULL, *node;

  336.     parent = NULL;
  337.     if ((node = rb_search_auxiliary(key, root, &parent)))
  338.     {
  339.         return root;
  340.     }

  341.     node = rb_new_node(key, data);
  342.     node->parent = parent;
  343.     node->left = node->right = NULL;
  344.     node->color = RED;

  345.     if (parent)
  346.     {
  347.         if (parent->key > key)
  348.         {
  349.             parent->left = node;
  350.         }
  351.         else
  352.         {
  353.             parent->right = node;
  354.         }
  355.     }
  356.     else
  357.     {
  358.         root = node;
  359.     }

  360.     return rb_insert_rebalance(node, root);
  361. }

  362. rb_node_t* rb_search(key_t key, rb_node_t* root)
  363. {
  364.     return rb_search_auxiliary(key, root, NULL);
  365. }

  366. rb_node_t* rb_erase(key_t key, rb_node_t *root)
  367. {
  368.     rb_node_t *child, *parent, *old, *left, *node;
  369.     color_t color;

  370.     if (!(node = rb_search_auxiliary(key, root, NULL)))
  371.     {
  372.         printf("key %d is not exist!\n");
  373.         return root;
  374.     }

  375.     old = node;

  376.     if (node->left && node->right)
  377.     {
  378.         node = node->right;
  379.         while ((left = node->left) != NULL)
  380.         {
  381.             node = left;
  382.         }
  383.         child = node->right;
  384.         parent = node->parent;
  385.         color = node->color;

  386.         if (child)
  387.         {
  388.             child->parent = parent;
  389.         }
  390.         if (parent)
  391.         {
  392.             if (parent->left == node)
  393.             {
  394.                 parent->left = child;
  395.             }
  396.             else
  397.             {
  398.                 parent->right = child;
  399.             }
  400.         }
  401.         else
  402.         {
  403.             root = child;
  404.         }

  405.         if (node->parent == old)
  406.         {
  407.             parent = node;
  408.         }

  409.         node->parent = old->parent;
  410.         node->color = old->color;
  411.         node->right = old->right;
  412.         node->left = old->left;

  413.         if (old->parent)
  414.         {
  415.             if (old->parent->left == old)
  416.             {
  417.                 old->parent->left = node;
  418.             }
  419.             else
  420.             {
  421.                 old->parent->right = node;
  422.             }
  423.         }
  424.         else
  425.         {
  426.             root = node;
  427.         }

  428.         old->left->parent = node;
  429.         if (old->right)
  430.         {
  431.             old->right->parent = node;
  432.         }
  433.     }
  434.     else
  435.     {
  436.         if (!node->left)
  437.         {
  438.             child = node->right;
  439.         }
  440.         else if (!node->right)
  441.         {
  442.             child = node->left;
  443.         }
  444.         parent = node->parent;
  445.         color = node->color;

  446.         if (child)
  447.         {
  448.             child->parent = parent;
  449.         }
  450.         if (parent)
  451.         {
  452.             if (parent->left == node)
  453.             {
  454.                 parent->left = child;
  455.             }
  456.             else
  457.             {
  458.                 parent->right = child;
  459.             }
  460.         }
  461.         else
  462.         {
  463.             root = child;
  464.         }
  465.     }

  466.     free(old);

  467.     if (color == BLACK)
  468.     {
  469.         root = rb_erase_rebalance(child, parent, root);
  470.     }

  471.     return root;
  472. }


复制代码

[ 本帖最后由 converse 于 2008-11-11 19:20 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-12-30 23:11 |显示全部楼层

回复 #11 Godbach 的帖子

没用过内核中的红黑树接口,不好回答这个问题....但是感觉跟那个流传的很广泛的内核中使用的list应该原理类似.

论坛徽章:
0
3 [报告]
发表于 2008-12-30 23:24 |显示全部楼层

回复 #13 Godbach 的帖子

这简单啊,后序遍历树就OK啦...

论坛徽章:
0
4 [报告]
发表于 2008-12-30 23:30 |显示全部楼层

回复 #15 Godbach 的帖子

客气了,我这个代码也是copy别人的然后照着书改的

论坛徽章:
0
5 [报告]
发表于 2008-12-31 22:45 |显示全部楼层

回复 #23 Godbach 的帖子

确实如此,没有考虑周全,当时只想着写一个出来...

论坛徽章:
0
6 [报告]
发表于 2009-01-01 23:46 |显示全部楼层

回复 #28 Godbach 的帖子

应该可以有key重复的情况,stl中的multimap就是使用红黑树实现的,具体怎么做到的等我有空看了那部分代码再说.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP