tree.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /* The MIT License
  2. Copyright (C) 2011, 2012 Zilong Tan ([email protected])
  3. Permission is hereby granted, free of charge, to any person obtaining
  4. a copy of this software and associated documentation files (the
  5. "Software"), to deal in the Software without restriction, including
  6. without limitation the rights to use, copy, modify, merge, publish,
  7. distribute, sublicense, and/or sell copies of the Software, and to
  8. permit persons to whom the Software is furnished to do so, subject to
  9. the following conditions:
  10. The above copyright notice and this permission notice shall be
  11. included in all copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  13. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  14. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  15. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  16. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  17. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  18. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  19. SOFTWARE.
  20. */
  21. #ifndef _ULIB_TREE_H
  22. #define _ULIB_TREE_H
  23. #include <stddef.h>
  24. #ifdef __cplusplus
  25. #define new _new_
  26. #endif
  27. struct tree_root_np {
  28. struct tree_root_np *left, *right;
  29. };
  30. struct tree_root {
  31. struct tree_root *left, *right, *parent;
  32. };
  33. struct avl_root {
  34. struct avl_root *left, *right, *parent;
  35. int balance:3;
  36. };
  37. #define TREE_ROOT_NP_INIT { NULL, NULL }
  38. #define TREE_ROOT_NP(name) \
  39. struct tree_root_np name = TREE_ROOT_NP_INIT
  40. #define INIT_TREE_ROOT_NP(ptr) do { \
  41. (ptr)->left = (ptr)->right = NULL; \
  42. } while (0)
  43. #define TREE_ROOT_INIT { NULL, NULL, NULL }
  44. #define TREE_ROOT(name) \
  45. struct tree_root name = TREE_ROOT_INIT
  46. #define INIT_TREE_ROOT(ptr) do { \
  47. (ptr)->left = NULL; \
  48. (ptr)->right = NULL; \
  49. (ptr)->parent = NULL; \
  50. } while (0)
  51. #define AVL_ROOT_INIT { NULL, NULL, NULL, 0 }
  52. #define AVL_ROOT(name) \
  53. struct avl_root name = AVL_ROOT_INIT;
  54. #define INIT_AVL_ROOT(ptr) do { \
  55. INIT_TREE_ROOT(ptr); \
  56. (ptr)->balance = 0; \
  57. } while (0)
  58. #define TREE_NP_ISEMPTY(ptr) ((ptr) == NULL)
  59. #define TREE_ISEMPTY(ptr) TREE_NP_ISEMPTY(ptr)
  60. #define SPLAY_ISEMPTY(ptr) TREE_NP_ISEMPTY(ptr)
  61. #define AVL_ISEMPTY(ptr) TREE_NP_ISEMPTY(ptr)
  62. #ifdef __cplusplus
  63. extern "C" {
  64. #endif
  65. struct tree_root_np *
  66. tree_search(struct tree_root_np *entry,
  67. int (*compare)(const void *, const void *),
  68. struct tree_root_np *root);
  69. #define TREE_SEARCH(entry, comp, root) \
  70. tree_search((struct tree_root_np*)(entry), \
  71. (int (*)(const void *, const void *))(comp), \
  72. (struct tree_root_np*)(root))
  73. struct tree_root_np *
  74. tree_min(struct tree_root_np *root);
  75. #define TREE_MIN(root) \
  76. tree_min((struct tree_root_np*)(root))
  77. struct tree_root_np *
  78. tree_max(struct tree_root_np *root);
  79. #define TREE_MAX(root) \
  80. tree_max((struct tree_root_np*)(root))
  81. struct tree_root *
  82. tree_successor(struct tree_root *entry);
  83. #define TREE_SUCCESSOR(entry) \
  84. tree_successor((struct tree_root*)(entry))
  85. struct tree_root *
  86. tree_predecessor(struct tree_root *entry);
  87. #define TREE_PREDECESSOR(entry) \
  88. tree_predecessor((struct tree_root*)(entry))
  89. /* add a new entry ignoring any duplicates */
  90. void tree_add(struct tree_root *new,
  91. int (*compare)(const void *, const void *),
  92. struct tree_root **root);
  93. #define TREE_ADD(new, comp, root) \
  94. tree_add((struct tree_root*)(new), \
  95. (int (*)(const void *, const void *))(comp), \
  96. (struct tree_root**)(root))
  97. /* add a unique entry
  98. if the entry already exists, return the old one; otherwise
  99. the new entry will be returned. */
  100. struct tree_root *
  101. tree_map(struct tree_root *new,
  102. int (*compare)(const void *, const void *),
  103. struct tree_root **root);
  104. #define TREE_MAP(new, comp, root) \
  105. tree_map((struct tree_root*)(new), \
  106. (int (*)(const void *, const void *))(comp), \
  107. (struct tree_root**)(root))
  108. void tree_del(struct tree_root *entry, struct tree_root **root);
  109. #define TREE_DEL(entry, root) \
  110. tree_del((struct tree_root*)(entry), \
  111. (struct tree_root**)(root))
  112. /* in addition to the tree_map, this operation splays the tree */
  113. struct tree_root *
  114. splay_map(struct tree_root *new,
  115. int (*compare)(const void *, const void *),
  116. struct tree_root **root);
  117. #define SPLAY_MAP(new, comp, root) \
  118. splay_map((struct tree_root*)(new), \
  119. (int (*)(const void *, const void *))(comp), \
  120. (struct tree_root**)(root))
  121. struct tree_root_np *
  122. splay_map_np(struct tree_root_np *new,
  123. int (*compare)(const void *, const void *),
  124. struct tree_root_np **root);
  125. #define SPLAY_MAP_NP(new, comp, root) \
  126. splay_map_np((struct tree_root_np*)(new), \
  127. (int (*)(const void *, const void *))(comp), \
  128. (struct tree_root_np**)(root))
  129. struct tree_root *
  130. splay_search(struct tree_root *entry,
  131. int (*compare)(const void *, const void *),
  132. struct tree_root **root);
  133. #define SPLAY_SEARCH(entry, comp, root) \
  134. splay_search((struct tree_root*)(entry), \
  135. (int (*)(const void *, const void *))(comp), \
  136. (struct tree_root**)(root))
  137. struct tree_root_np *
  138. splay_search_np(struct tree_root_np *entry,
  139. int (*compare)(const void *, const void *),
  140. struct tree_root_np **root);
  141. #define SPLAY_SEARCH_NP(entry, comp, root) \
  142. splay_search_np((struct tree_root_np*)(entry), \
  143. (int (*)(const void *, const void *))(comp), \
  144. (struct tree_root_np**)(root))
  145. void avl_add(struct avl_root *new,
  146. int (*compare)(const void *, const void *),
  147. struct avl_root **root);
  148. #define AVL_ADD(new, comp, root) \
  149. avl_add((struct avl_root*)(new), \
  150. (int (*)(const void *, const void *))(comp), \
  151. (struct avl_root**)(root))
  152. struct avl_root *
  153. avl_map(struct avl_root *new,
  154. int (*compare)(const void *, const void *),
  155. struct avl_root **root);
  156. #define AVL_MAP(new, comp, root) \
  157. avl_map((struct avl_root*)(new), \
  158. (int (*)(const void *, const void *))(comp), \
  159. (struct avl_root**)(root))
  160. void avl_del(struct avl_root *entry, struct avl_root **root);
  161. #define AVL_DEL(entry, root) \
  162. avl_del((struct avl_root*)(entry), \
  163. (struct avl_root**)(root))
  164. #ifdef __cplusplus
  165. }
  166. #endif
  167. /* retrieves the address of the host struct.
  168. * @ptr is the pointer to the embedded struct of which the name is
  169. * provided by @member, and @type indicates the host struct type. */
  170. #define tree_entry(ptr, type, member) \
  171. ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
  172. #define avl_entry(ptr, type, member) tree_entry(ptr, type, member)
  173. #define tree_for_each(pos, root) \
  174. for (pos = (typeof(pos))TREE_MIN(root); pos != NULL; \
  175. pos = (typeof(pos))TREE_SUCCESSOR(pos))
  176. #define tree_for_each_prev(pos, root) \
  177. for (pos = (typeof(pos))TREE_MAX(root); pos != NULL; \
  178. pos = (typeof(pos))TREE_PREDECESSOR(pos))
  179. #define tree_for_each_safe(pos, n, root) \
  180. for (pos = (typeof(pos))TREE_MIN(root), n = (typeof(n))TREE_SUCCESSOR(pos); \
  181. pos != NULL; \
  182. pos = n, n = n? (typeof(n))TREE_SUCCESSOR(n): NULL)
  183. #define tree_for_each_entry(pos, root, member) \
  184. for (pos = tree_entry(TREE_MIN(root), typeof(*pos), member); \
  185. &pos->member != NULL; \
  186. pos = tree_entry(TREE_SUCCESSOR(&pos->member), typeof(*pos), member))
  187. #define tree_for_each_entry_safe(pos, n, root, member) \
  188. for (pos = tree_entry(TREE_MIN(root), typeof(*pos), member), \
  189. n = tree_entry(TREE_SUCCESSOR(&pos->member), typeof(*pos), member); \
  190. &pos->member != NULL; \
  191. pos = n, n = tree_entry(&n->member != NULL? \
  192. TREE_SUCCESSOR(&n->member): NULL, \
  193. typeof(*n), member))
  194. #define avl_for_each(pos, root) \
  195. for (pos = (struct avl_root *)TREE_MIN(root); pos != NULL; \
  196. pos = (struct avl_root *)TREE_SUCCESSOR(pos))
  197. #define avl_for_each_prev(pos, root) \
  198. for (pos = (struct avl_root *)TREE_MAX(root); pos != NULL; \
  199. pos = (struct avl_root *)TREE_PREDECESSOR(pos))
  200. #define avl_for_each_safe(pos, n, root) \
  201. for (pos = (struct avl_root *)TREE_MIN(root), \
  202. n = (struct avl_root *)TREE_SUCCESSOR(pos); \
  203. pos != NULL; \
  204. pos = n, n = n != NULL? (struct avl_root *)TREE_SUCCESSOR(n): NULL)
  205. #define avl_for_each_entry(pos, root, member) \
  206. for (pos = tree_entry(TREE_MIN(root), typeof(*pos), member); \
  207. &pos->member != NULL; \
  208. pos = tree_entry(TREE_SUCCESSOR(&pos->member), typeof(*pos), member))
  209. #define avl_for_each_entry_safe(pos, n, root, member) \
  210. for (pos = tree_entry(TREE_MIN(root), typeof(*pos), member), \
  211. n = tree_entry(TREE_SUCCESSOR(&pos->member), typeof(*pos), member); \
  212. &pos->member != NULL; \
  213. pos = n, n = tree_entry(&n->member != NULL? \
  214. TREE_SUCCESSOR(&n->member): NULL, \
  215. typeof(*n), member))
  216. #ifdef __cplusplus
  217. #undef new
  218. #endif
  219. #endif /* _ULIB_TREE_H */