rbtree.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /* ----------------------------------------------------------------------- *
  2. *
  3. * Copyright 1996-2009 The NASM Authors - All Rights Reserved
  4. * See the file AUTHORS included with the NASM distribution for
  5. * the specific copyright holders.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following
  9. * conditions are met:
  10. *
  11. * * Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * * Redistributions in binary form must reproduce the above
  14. * copyright notice, this list of conditions and the following
  15. * disclaimer in the documentation and/or other materials provided
  16. * with the distribution.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  19. * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
  20. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  23. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  25. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  27. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  28. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  29. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  30. * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. * ----------------------------------------------------------------------- */
  33. /*
  34. * rbtree.c
  35. *
  36. * Simple implementation of a left-leaning red-black tree with 64-bit
  37. * integer keys. The search operation will return the highest node <=
  38. * the key; only search and insert are supported, but additional
  39. * standard llrbtree operations can be coded up at will.
  40. *
  41. * See http://www.cs.princeton.edu/~rs/talks/LLRB/RedBlack.pdf for
  42. * information about left-leaning red-black trees.
  43. */
  44. #include "rbtree.h"
  45. struct rbtree *rb_search(struct rbtree *tree, uint64_t key)
  46. {
  47. struct rbtree *best = NULL;
  48. while (tree) {
  49. if (tree->key == key)
  50. return tree;
  51. else if (tree->key > key)
  52. tree = tree->left;
  53. else {
  54. best = tree;
  55. tree = tree->right;
  56. }
  57. }
  58. return best;
  59. }
  60. static bool is_red(struct rbtree *h)
  61. {
  62. return h && h->red;
  63. }
  64. static struct rbtree *rotate_left(struct rbtree *h)
  65. {
  66. struct rbtree *x = h->right;
  67. h->right = x->left;
  68. x->left = h;
  69. x->red = x->left->red;
  70. x->left->red = true;
  71. return x;
  72. }
  73. static struct rbtree *rotate_right(struct rbtree *h)
  74. {
  75. struct rbtree *x = h->left;
  76. h->left = x->right;
  77. x->right = h;
  78. x->red = x->right->red;
  79. x->right->red = true;
  80. return x;
  81. }
  82. static void color_flip(struct rbtree *h)
  83. {
  84. h->red = !h->red;
  85. h->left->red = !h->left->red;
  86. h->right->red = !h->right->red;
  87. }
  88. struct rbtree *rb_insert(struct rbtree *tree, struct rbtree *node)
  89. {
  90. if (!tree) {
  91. node->red = true;
  92. return node;
  93. }
  94. if (is_red(tree->left) && is_red(tree->right))
  95. color_flip(tree);
  96. if (node->key < tree->key)
  97. tree->left = rb_insert(tree->left, node);
  98. else
  99. tree->right = rb_insert(tree->right, node);
  100. if (is_red(tree->right))
  101. tree = rotate_left(tree);
  102. if (is_red(tree->left) && is_red(tree->left->left))
  103. tree = rotate_right(tree);
  104. return tree;
  105. }