Chinaunix首页 | 论坛 | 博客
  • 博客访问: 12948
  • 博文数量: 16
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 170
  • 用 户 组: 普通用户
  • 注册时间: 2013-05-08 11:44
文章分类
文章存档

2014年(16)

我的朋友
最近访客

分类: C/C++

2014-05-19 14:45:03


点击(此处)折叠或打开

  1. #define RED 0
  2. #define BLACK 1
  3. #define MASK 3

  4. #define container_of(pointer, type, member) (type *) ((char*)pointer - offsetof(type, member));
  5. struct rb_node {
  6.         int key; /**just for test***/
  7.         unsigned long parent_color; //
  8.         struct rb_node *lchild;
  9.         struct rb_node *rchild;
  10. };
  11. struct rb_head {
  12.         //int count;
  13.         struct rb_node *head;
  14. };

  15. void init_head(struct rb_head *root)
  16. {
  17.         root->head = NULL;
  18. }

  19. bool is_red(struct rb_node *node)
  20. {
  21.         unsigned long color;
  22.         if (node)
  23.                 color = node->parent_color & MASK;
  24.         else
  25.                 color = BLACK;
  26.         return color == RED;
  27. }

  28. #define is_black(node) (!is_red(node))
  29. /**** color == -1 表示color颜色不变****/
  30. static inline void set_parent_color(struct rb_node *node, \
  31.                 struct rb_node *p, int color)
  32. {
  33.         if (node) {
  34.                 if (color == -1)
  35.                         color = node->parent_color & MASK;
  36.                 node->parent_color = (unsigned long) p | color;
  37.         }
  38. }

  39. struct rb_node *get_parent(struct rb_node *node)
  40. {
  41.         if (node)
  42.                 return (struct rb_node *) (node->parent_color & ~MASK);
  43.         else
  44.                 return NULL;
  45. }


  46. /*(which) must be pointed to the address of one of parent's children*/
  47. void rb_new_link(struct rb_node *new, struct rb_node *parent,\
  48.                 struct rb_node **which)
  49. {
  50.         new->parent_color = (unsigned long) parent;
  51.         new->lchild = new->rchild = NULL;
  52.         *which = new;
  53. }

  54. static void rb_change_link(struct rb_node *new, struct rb_node *old, \
  55.                 struct rb_node *father, struct rb_head *root)
  56. {
  57.         if (father) {
  58.                 if (old == father->lchild)
  59.                         father->lchild = new;
  60.                 else
  61.                         father->rchild = new;
  62.         } else
  63.                 root->head = new;
  64. }void rb_insert(struct rb_node *new, struct rb_head *root)
  65. {
  66.         struct rb_node *parent, *gp, *tmp;

  67.         parent = get_parent(new);
  68.         while (true) {
  69.                 /*case 1; reach the root*/
  70.                 if (!parent) {
  71.                         set_parent_color(new, NULL, BLACK);
  72.                         break;
  73.                 }
  74.                 /*case 2: father is black*/
  75.                 if (is_black(parent))
  76.                         break;

  77.                 gp = get_parent(parent);

  78.                 /*case 3: father is red, uncle is red*/
  79.                 if (is_red(gp->lchild) && is_red(gp->rchild)) {
  80.                         set_parent_color(gp->lchild, gp, BLACK);
  81.                         set_parent_color(gp->rchild, gp, BLACK);

  82.                         new = gp;
  83.                         parent = get_parent(new);
  84.                         set_parent_color(new, parent, RED);
  85.                         continue;
  86.                 }
  87.                 /*case 4: father is red, uncle is black*/
  88.                 if (gp->lchild == parent) {
  89.                         if (new == parent->rchild) {

  90.                                 parent->rchild = new->lchild;
  91.                                 new->lchild = parent;
  92.                                 /*after rotating, didn't chage new's father*/
  93.                                 set_parent_color(parent->rchild, parent, BLACK);
  94.                                 set_parent_color(parent, new, RED);

  95.                                 tmp = parent;
  96.                                 parent = new;
  97.                                 new = tmp;
  98.                                 /***need do a right rotate followed***/
  99.                         }
  100.               tmp = get_parent(gp); //record the gp's father

  101.                         gp->lchild = parent->rchild;
  102.                         parent->rchild = gp;

  103.                         set_parent_color(gp->lchild, gp, BLACK);
  104.                         set_parent_color(gp, parent, RED);
  105.                         set_parent_color(parent, tmp, BLACK);

  106.                         rb_change_link(parent, gp, tmp, root);
  107.                         break;
  108.                 } else {
  109.                         if (new == parent->lchild) {
  110.                                 parent->lchild = new->rchild;
  111.                                 new->rchild = parent;

  112.                                 set_parent_color(parent->lchild, parent, BLACK);
  113.                                 set_parent_color(parent, new, RED);

  114.                                 tmp = parent;
  115.                                 parent = new;
  116.                                 new = tmp;
  117.                         }
  118.   tmp = get_parent(gp);

  119.                         gp->rchild = parent->lchild;
  120.                         parent->lchild = gp;

  121.                         set_parent_color(gp->rchild, gp, BLACK);
  122.                         set_parent_color(gp, parent, RED);
  123.                         set_parent_color(parent, tmp, BLACK);

  124.                         rb_change_link(parent, gp, tmp, root);
  125.                         break;
  126.                 }
  127.         }
  128. }
  129. void do_del(struct rb_node *parent, struct rb_head *root)
  130. {
  131.         struct rb_node *now, *sibling, *gp;
  132.         struct rb_node *sl, *sr;

  133.         now = NULL;

  134.         while (true) {
  135.                 bool parent_is_red;
  136.                 gp = get_parent(parent);
  137.                 if (now == parent->lchild) {
  138.                         sibling = parent->rchild;
  139.                         /* case 1; sibling is red */
  140.                         if (is_red(sibling)) {
  141.                                 parent->rchild = sibling->lchild;
  142.                                 sibling->lchild = parent;

  143.                                 set_parent_color(parent->rchild, parent, BLACK);
  144.                                 set_parent_color(parent, sibling, RED);
  145.                                 set_parent_color(sibling, gp, BLACK);

  146.                                 rb_change_link(sibling, parent, gp, root);
  147.                                 sibling = parent->rchild;

  148.                         }

  149.                         parent_is_red = is_red(parent);
  150.                         sl = sibling->lchild;
  151.                         sr = sibling->rchild;
  152.                         /*case 2: sibling is black, sibling's children are black*/
  153.  if (is_black(sl) && is_black(sr)) {

  154.                                 set_parent_color(sibling, parent, RED);
  155.                                 set_parent_color(parent, gp, BLACK);

  156.                                 if (parent_is_red || gp == NULL) //gp == NULL ,可以排除parent_is_black但gp==NULL
  157.                                         break;
  158.                                 else if (gp){
  159.                                         now = parent;
  160.                                         parent = gp;
  161.                                         continue;
  162.                                 }
  163.                         }
  164.                         /*case 3: sibling is balck, and slibling's lchild is red*/
  165.                         if (is_red(sl) && is_black(sr)) {
  166.                                 sibling->lchild = sl->rchild;
  167.                                 sl->rchild = sibling;

  168.                                 set_parent_color(sibling->lchild, sibling, BLACK);
  169.                                 set_parent_color(sibling, sl, RED);
  170.                                 set_parent_color(sl, parent, BLACK);

  171.                                 sibling = sl;
  172.                                 sl = sibling->lchild;
  173.                                 sr = sibling->rchild;
  174.                         }
  175.                         /*case 4: sibling is black, and slibling's rchild is red*/
  176.   parent->rchild = sl;
  177.                         sibling->lchild = parent;

  178.                         set_parent_color(parent->rchild, parent, -1);
  179.                         set_parent_color(parent, sibling, BLACK);
  180.                         set_parent_color(sr, sibling, BLACK);
  181.                         if (parent_is_red)
  182.                                 set_parent_color(sibling, gp, RED);
  183.                         else
  184.                                 set_parent_color(sibling, gp, BLACK);

  185.                         rb_change_link(sibling, parent, gp, root);
  186.                         break;
  187.                 } else {
  188.                         sibling = parent->lchild;

  189.                         if (is_red(sibling)) {
  190.                                 parent->lchild = sibling->rchild;
  191.                                 sibling->rchild = parent;

  192.                                 set_parent_color(parent->lchild, parent, BLACK);
  193.                                 set_parent_color(parent, sibling, RED);
  194.                                 set_parent_color(sibling, gp, BLACK);

  195.                                 rb_change_link(sibling, parent, gp, root);

  196.                                 sibling = parent->lchild;
  197.                         }
  198.  sl = sibling->lchild;
  199.                         sr = sibling->rchild;
  200.                         parent_is_red = is_red(parent);

  201.                         if (is_black(sl) && is_black(sr)) {

  202.                                 set_parent_color(sibling, parent, RED);
  203.                                 set_parent_color(parent, gp, BLACK);

  204.                                 if (parent_is_red)
  205.                                         break;
  206.                                 else if (gp) {
  207.                                         now = parent;
  208.                                         parent = gp;
  209.                                         continue;
  210.                                 } else
  211.                                         break;
  212.                         }
  213.  if (is_red(sr) && is_black(sl)) {
  214.                                 sibling->rchild = sr->lchild;
  215.                                 sr->lchild = sibling;

  216.                                 set_parent_color(sibling->rchild, sibling, BLACK);
  217.                                 set_parent_color(sibling, sr, RED);
  218.                                 set_parent_color(sr, parent, BLACK);

  219.                                 sibling = sr;
  220.                                 sl = sibling->lchild;
  221.                                 sr = sibling->rchild;
  222.                         }

  223.                         parent->lchild = sr;
  224.                         sibling->rchild = parent;

  225.                         set_parent_color(parent->lchild, parent, -1);
  226.                         set_parent_color(parent, sibling, BLACK);
  227.                         set_parent_color(sl, sibling, BLACK);

  228.                         if (parent_is_red)
  229.                                 set_parent_color(sibling, gp, RED);
  230.                         else
  231.                                 set_parent_color(sibling, gp, BLACK);

  232.                         rb_change_link(sibling, parent, gp, root);
  233.                         break;
  234.                 }
  235.         }
  236. }void rb_del(struct rb_node *node, struct rb_head *root)
  237. {
  238.         struct rb_node *child, *parent;
  239.         struct rb_node *victim;

  240.         victim = node;
  241.         if (node->lchild && node->rchild) {
  242.                 victim = node->lchild;
  243.                 while (victim->rchild)
  244.                         victim = victim->rchild;
  245.         }

  246.         parent = get_parent(victim);
  247.         child = victim->lchild ? victim->lchild : victim->rchild;


  248. /***now , node only has no more one child
  249. *case 1: node is red and a real leaf; node is not root;
  250. *case 2: node is black with a red child; node maybe the root;
  251. *case 3: node is black and real leaf; node maybe the root;
  252. */
  253.  rb_change_link(child, victim, parent, root);
  254.         /*case 2*/
  255.         if (child)
  256.                 set_parent_color(child, parent, BLACK);
  257.         /***case 3****/
  258.         else if(is_black(victim) && parent)
  259.                 do_del(parent, root);
  260.         if (victim != node) {
  261.                 *victim = *node;
  262.                 set_parent_color(victim->lchild, victim, -1);
  263.                 set_parent_color(victim->rchild, victim, -1);
  264.                 rb_change_link(victim, node, get_parent(node), root);
  265.         }
  266. }
  267. void del(struct rb_head *root, int key)
  268. {
  269.         struct test_elem *elem;
  270.         struct rb_node *node, *parent;

  271.         node = root->head;

  272.         while (node) {
  273.                 int ret = cmp(key, node);
  274.                 if (ret < 0)
  275.                         node = node->lchild;
  276.                 else if (ret > 0)
  277.                         node = node->rchild;
  278.                 else
  279.                         break;
  280.         }

  281.         if (node) {
  282.                 rb_del(node, root);
  283.                 elem = container_of(node, struct test_elem, node);
  284.                 free (elem);
  285.         } else
  286.                 fprintf(stderr, "del : this key is not bound\n");
  287. }
  288. struct test_elem {
  289.         int key;
  290.         struct rb_node node;
  291. };
  292. static int cmp(int key, const struct rb_node *sec)
  293. {
  294.         struct test_elem *elem;
  295.         elem = container_of(sec, struct test_elem, node);
  296.         return key - elem->key;
  297. }
  298. void insert(struct rb_head *root, int key)
  299. {
  300.         struct rb_node *parent, **which;
  301.         struct rb_node *node;
  302.         struct test_elem *data;
  303.         int ret;

  304.         parent = root->head;
  305.         which = &root->head; //-> prior to &
  306.         while (*which) {
  307.                 parent = *which;
  308.                 ret = cmp(key, *which);
  309.                 if (ret < 0)
  310.                         which = &(*which)->lchild;
  311.                 else if (ret > 0)
  312.                         which = &(*which)->rchild;
  313.                 else
  314.                         break;
  315.         }

  316.         if (*which) {
  317.                 fprintf(stderr, "my_insert: this key has been bound!\n");
  318.         }else {
  319.  data = malloc(sizeof(struct test_elem)); //suppose malloc always succeed
  320.                 data->key = key;
  321.                 node = &data->node;
  322.                 rb_new_link(node, parent, which);
  323.                 rb_insert(node, root);
  324.         }

  325. }
  326. void do_travel(struct rb_node *node)
  327. {
  328.         struct rb_node *father;
  329.         struct test_elem *elem;
  330.         int key, f;
  331.         char c;
  332.         if (node) {
  333.                 do_travel(node->lchild);
  334.                 elem = container_of(node, struct test_elem, node);
  335.                 key = elem->key;

  336.                 father = get_parent(node);
  337.                 elem = container_of(father, struct test_elem, node);
  338.                 f = father ? elem->key : -1;

  339.                 c = is_red(node) ? 'r' : 'b';

  340.                 printf("%d:%c:%d ", key, c, f);
  341.                 do_travel(node->rchild);
  342.         }
  343. }

  344. void travel(struct rb_head *root)
  345. {
  346.         do_travel(root->head);
  347.         printf("\n");
  348. }
  349. int main()
  350. {
  351.         struct rb_head root;
  352.         init_head(&root);

  353.         while (true);
  354.         return 0;
  355. }

阅读(151) | 评论(0) | 转发(0) |
0

上一篇:BM

下一篇:treap

给主人留下些什么吧!~~