cs_rbtree.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. /**
  2. * cs_rbtree.c
  3. * Copyright (c) 2007-2018 ls
  4. **/
  5. #include "../inc/cs.h"
  6. #include "../inc/cs_rbtree.h"
  7. CS_API void cs_rbtree_init(
  8. cs_rbtree_t *t, cs_rbtree_node_t *nil, int (*cmp)(void *, void *)) {
  9. CS_TREE_RB_BLACK(nil);
  10. nil->key = 0;
  11. nil->parent = nil->left = nil->right = nil;
  12. t->nil = nil;
  13. t->root = nil;
  14. t->cmp = cmp;
  15. }
  16. static cs_inline void cs_rbtree_left_rotate(
  17. cs_rbtree_t *t, cs_rbtree_node_t *x) {
  18. cs_rbtree_node_t *y;
  19. cs_rbtree_node_t *nil = t->nil;
  20. y = x->right;
  21. x->right = y->left;
  22. if (y->left != nil) {
  23. y->left->parent = x;
  24. }
  25. y->parent = x->parent;
  26. if (x == x->parent->left) {
  27. x->parent->left = y;
  28. } else {
  29. x->parent->right = y;
  30. }
  31. y->left = x;
  32. x->parent = y;
  33. }
  34. static cs_inline void cs_rbtree_right_rotate(
  35. cs_rbtree_t *t, cs_rbtree_node_t *x) {
  36. cs_rbtree_node_t *y;
  37. cs_rbtree_node_t *nil = t->nil;
  38. y = x->left;
  39. x->left = y->right;
  40. if (nil != y->right) {
  41. y->right->parent = x;
  42. }
  43. y->parent = x->parent;
  44. if (x == x->parent->left) {
  45. x->parent->left = y;
  46. } else {
  47. x->parent->right = y;
  48. }
  49. y->right = x;
  50. x->parent = y;
  51. }
  52. CS_API cs_rbtree_node_t *cs_rbtree_add(cs_rbtree_t *t, cs_rbtree_node_t *n) {
  53. cs_rbtree_node_t *x;
  54. cs_rbtree_node_t *y;
  55. cs_rbtree_node_t *nil = t->nil;
  56. n->left = n->right = nil;
  57. y = t->root;
  58. x = t->root->left;
  59. while (x != nil) {
  60. if (CS_TREE_RB_EQ(t, n->key, x->key)) {
  61. return (x);
  62. }
  63. y = x;
  64. x = CS_TREE_RB_LT(t, n->key, x->key) ? x->left : x->right;
  65. if (x->key == nil->key) {
  66. break;
  67. }
  68. }
  69. n->parent = y;
  70. if ((y == t->root) || CS_TREE_RB_LT(t, n->key, y->key)) {
  71. y->left = n;
  72. } else {
  73. y->right = n;
  74. }
  75. CS_TREE_RB_RED(n);
  76. while (CS_TREE_RB_ISRED(n->parent)) {
  77. /* use sentinel instead of checking for root */
  78. //printf("CS_TREE_RB_ISRED:%08x\n",n->parent->key);
  79. if (n->parent == n->parent->parent->left) {
  80. y = n->parent->parent->right;
  81. if (CS_TREE_RB_ISRED(y)) {
  82. CS_TREE_RB_BLACK(n->parent);
  83. CS_TREE_RB_BLACK(y);
  84. CS_TREE_RB_RED(n->parent->parent);
  85. n = n->parent->parent;
  86. } else {
  87. if (n == n->parent->right) {
  88. n = n->parent;
  89. cs_rbtree_left_rotate(t, n);
  90. }
  91. CS_TREE_RB_BLACK(n->parent);
  92. CS_TREE_RB_RED(n->parent->parent);
  93. cs_rbtree_right_rotate(t, n->parent->parent);
  94. }
  95. } else {
  96. y = n->parent->parent->left;
  97. if (CS_TREE_RB_ISRED(y)) {
  98. CS_TREE_RB_BLACK(n->parent);
  99. CS_TREE_RB_BLACK(y);
  100. CS_TREE_RB_RED(n->parent->parent);
  101. n = n->parent->parent;
  102. } else {
  103. if (n == n->parent->left) {
  104. n = n->parent;
  105. cs_rbtree_right_rotate(t, n);
  106. }
  107. CS_TREE_RB_BLACK(n->parent);
  108. CS_TREE_RB_RED(n->parent->parent);
  109. cs_rbtree_left_rotate(t, n->parent->parent);
  110. }
  111. }
  112. }
  113. CS_TREE_RB_BLACK(t->root->left);
  114. return (NULL);
  115. }
  116. static cs_inline void cs_rbtree_deletefixup(
  117. cs_rbtree_t *t, cs_rbtree_node_t *x) {
  118. cs_rbtree_node_t *root = t->root->left;
  119. cs_rbtree_node_t *w;
  120. while (CS_TREE_RB_ISBLACK(x) && (root != x)) {
  121. if (x == x->parent->left) {
  122. w = x->parent->right;
  123. if (CS_TREE_RB_ISRED(w)) {
  124. CS_TREE_RB_BLACK(w);
  125. CS_TREE_RB_RED(x->parent);
  126. cs_rbtree_left_rotate(t, x->parent);
  127. w = x->parent->right;
  128. }
  129. if (CS_TREE_RB_ISBLACK(w->right) && CS_TREE_RB_ISBLACK(w->left)) {
  130. CS_TREE_RB_RED(w);
  131. x = x->parent;
  132. } else {
  133. if (CS_TREE_RB_ISBLACK(w->right)) {
  134. CS_TREE_RB_BLACK(w->left);
  135. CS_TREE_RB_RED(w);
  136. cs_rbtree_right_rotate(t, w);
  137. w = x->parent->right;
  138. }
  139. CS_TREE_RB_CPYCOLOR(w, x->parent);
  140. CS_TREE_RB_BLACK(x->parent);
  141. CS_TREE_RB_BLACK(w->right);
  142. cs_rbtree_left_rotate(t, x->parent);
  143. x = root;
  144. }
  145. } else {
  146. w = x->parent->left;
  147. if(CS_TREE_RB_ISRED(w)) {
  148. CS_TREE_RB_BLACK(w);
  149. CS_TREE_RB_RED(x->parent);
  150. cs_rbtree_right_rotate(t, x->parent);
  151. w = x->parent->left;
  152. }
  153. if (CS_TREE_RB_ISBLACK(w->right) && CS_TREE_RB_ISBLACK(w->left)) {
  154. CS_TREE_RB_RED(w);
  155. x = x->parent;
  156. } else {
  157. if (CS_TREE_RB_ISBLACK(w->left)) {
  158. CS_TREE_RB_BLACK(w->right);
  159. CS_TREE_RB_RED(w);
  160. cs_rbtree_left_rotate(t, w);
  161. w = x->parent->left;
  162. }
  163. CS_TREE_RB_CPYCOLOR(w, x->parent);
  164. CS_TREE_RB_BLACK(x->parent);
  165. CS_TREE_RB_BLACK(w->left);
  166. cs_rbtree_right_rotate(t, x->parent);
  167. x = root;
  168. }
  169. }
  170. }
  171. CS_TREE_RB_BLACK(x);
  172. }
  173. static cs_inline cs_rbtree_node_t *cs_rbtree_successor(
  174. cs_rbtree_t *t, cs_rbtree_node_t *n) {
  175. cs_rbtree_node_t *y;
  176. cs_rbtree_node_t *nil = t->nil;
  177. cs_rbtree_node_t *root = t->root;
  178. if (nil != (y = n->right)) {
  179. while (y->left != nil) {
  180. y = y->left;
  181. }
  182. } else {
  183. y = n->parent;
  184. while (n == y->right) {
  185. n = y;
  186. y = y->parent;
  187. }
  188. if (y == root){
  189. return (nil);
  190. }
  191. }
  192. return (y);
  193. }
  194. CS_API void cs_rbtree_del(cs_rbtree_t *t, cs_rbtree_node_t *n) {
  195. cs_rbtree_node_t *y;
  196. cs_rbtree_node_t *x;
  197. cs_rbtree_node_t *nil = t->nil;
  198. cs_rbtree_node_t *root = t->root;
  199. y = ((n->left == nil) || (n->right == nil))
  200. ? n : cs_rbtree_successor(t, n);
  201. x = (y->left == nil) ? y->right : y->left;
  202. if (root == (x->parent = y->parent)) {
  203. root->left = x;
  204. } else {
  205. if (y == y->parent->left) {
  206. y->parent->left = x;
  207. } else {
  208. y->parent->right = x;
  209. }
  210. }
  211. if (y != n) {
  212. if(CS_TREE_RB_ISBLACK(y)){
  213. cs_rbtree_deletefixup(t, x);
  214. }
  215. y->left = n->left;
  216. y->right = n->right;
  217. y->parent = n->parent;
  218. CS_TREE_RB_CPYCOLOR(y, n);
  219. n->left->parent = n->right->parent = y;
  220. if (n == n->parent->left) {
  221. n->parent->left = y;
  222. } else {
  223. n->parent->right = y;
  224. }
  225. } else {
  226. if (CS_TREE_RB_ISBLACK(y)) {
  227. cs_rbtree_deletefixup(t, x);
  228. }
  229. }
  230. }
  231. static void cs_rbtree_order_internal(
  232. cs_rbtree_t *t,
  233. cs_rbtree_node_t *n,
  234. void (*cs_rbtree_callback)(cs_rbtree_node_t *)) {
  235. if (n == t->nil) {
  236. return;
  237. }
  238. cs_rbtree_order_internal(t, n->left, cs_rbtree_callback);
  239. cs_rbtree_callback(n);
  240. cs_rbtree_order_internal(t,n->right, cs_rbtree_callback);
  241. }
  242. CS_API void cs_rbtree_order(
  243. cs_rbtree_t *t,
  244. void (*cs_rbtree_callback)(cs_rbtree_node_t *)) {
  245. cs_rbtree_order_internal(t, t->root->left, cs_rbtree_callback);
  246. }
  247. CS_API cs_rbtree_node_t *cs_rbtree_query(cs_rbtree_t *t, void *k) {
  248. cs_rbtree_node_t *x = t->root->left;
  249. cs_rbtree_node_t *nil = t->nil;
  250. if (x == nil) {
  251. return (NULL);
  252. }
  253. while (!CS_TREE_RB_EQ(t, k, x->key)) {
  254. if (CS_TREE_RB_LT(t, k, x->key)) {
  255. x = x->left;
  256. } else {
  257. x = x->right;
  258. }
  259. if (x->key == nil->key) {
  260. return (NULL);
  261. }
  262. }
  263. return (x);
  264. }
  265. CS_API cs_rbtree_node_t *cs_rbtree_min(cs_rbtree_t *t) {
  266. cs_rbtree_node_t *n = t->root;
  267. while (n->left != t->nil) {
  268. n = n->left;
  269. if (n->key == t->nil->key) {
  270. return (NULL);
  271. }
  272. }
  273. return (n);
  274. }
  275. CS_API cs_rbtree_node_t *cs_rbtree_max(cs_rbtree_t *t) {
  276. cs_rbtree_node_t *n = t->root->left;
  277. while (n->right != t->nil) {
  278. n = n->right;
  279. if (n->key == t->nil->key) {
  280. return (NULL);
  281. }
  282. }
  283. return (n);
  284. }