gl_anytree_oset.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. /* Ordered set data type implemented by a binary tree.
  2. Copyright (C) 2006-2007, 2009-2013 Free Software Foundation, Inc.
  3. Written by Bruno Haible <bruno@clisp.org>, 2006.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. /* Common code of gl_avltree_oset.c and gl_rbtree_oset.c. */
  15. /* An item on the stack used for iterating across the elements. */
  16. typedef struct
  17. {
  18. gl_oset_node_t node;
  19. bool rightp;
  20. } iterstack_item_t;
  21. /* A stack used for iterating across the elements. */
  22. typedef iterstack_item_t iterstack_t[MAXHEIGHT];
  23. static gl_oset_t
  24. gl_tree_nx_create_empty (gl_oset_implementation_t implementation,
  25. gl_setelement_compar_fn compar_fn,
  26. gl_setelement_dispose_fn dispose_fn)
  27. {
  28. struct gl_oset_impl *set =
  29. (struct gl_oset_impl *) malloc (sizeof (struct gl_oset_impl));
  30. if (set == NULL)
  31. return NULL;
  32. set->base.vtable = implementation;
  33. set->base.compar_fn = compar_fn;
  34. set->base.dispose_fn = dispose_fn;
  35. set->root = NULL;
  36. set->count = 0;
  37. return set;
  38. }
  39. static size_t
  40. gl_tree_size (gl_oset_t set)
  41. {
  42. return set->count;
  43. }
  44. static bool
  45. gl_tree_search (gl_oset_t set, const void *elt)
  46. {
  47. gl_setelement_compar_fn compar = set->base.compar_fn;
  48. gl_oset_node_t node;
  49. for (node = set->root; node != NULL; )
  50. {
  51. int cmp = (compar != NULL
  52. ? compar (node->value, elt)
  53. : (node->value > elt ? 1 :
  54. node->value < elt ? -1 : 0));
  55. if (cmp < 0)
  56. node = node->right;
  57. else if (cmp > 0)
  58. node = node->left;
  59. else /* cmp == 0 */
  60. /* We have an element equal to ELT. */
  61. return true;
  62. }
  63. return false;
  64. }
  65. static bool
  66. gl_tree_search_atleast (gl_oset_t set,
  67. gl_setelement_threshold_fn threshold_fn,
  68. const void *threshold,
  69. const void **eltp)
  70. {
  71. gl_oset_node_t node;
  72. for (node = set->root; node != NULL; )
  73. {
  74. if (! threshold_fn (node->value, threshold))
  75. node = node->right;
  76. else
  77. {
  78. /* We have an element >= VALUE. But we need the leftmost such
  79. element. */
  80. gl_oset_node_t found = node;
  81. node = node->left;
  82. for (; node != NULL; )
  83. {
  84. if (! threshold_fn (node->value, threshold))
  85. node = node->right;
  86. else
  87. {
  88. found = node;
  89. node = node->left;
  90. }
  91. }
  92. *eltp = found->value;
  93. return true;
  94. }
  95. }
  96. return false;
  97. }
  98. static gl_oset_node_t
  99. gl_tree_search_node (gl_oset_t set, const void *elt)
  100. {
  101. gl_setelement_compar_fn compar = set->base.compar_fn;
  102. gl_oset_node_t node;
  103. for (node = set->root; node != NULL; )
  104. {
  105. int cmp = (compar != NULL
  106. ? compar (node->value, elt)
  107. : (node->value > elt ? 1 :
  108. node->value < elt ? -1 : 0));
  109. if (cmp < 0)
  110. node = node->right;
  111. else if (cmp > 0)
  112. node = node->left;
  113. else /* cmp == 0 */
  114. /* We have an element equal to ELT. */
  115. return node;
  116. }
  117. return NULL;
  118. }
  119. static int
  120. gl_tree_nx_add (gl_oset_t set, const void *elt)
  121. {
  122. gl_setelement_compar_fn compar;
  123. gl_oset_node_t node = set->root;
  124. if (node == NULL)
  125. {
  126. if (gl_tree_nx_add_first (set, elt) == NULL)
  127. return -1;
  128. return true;
  129. }
  130. compar = set->base.compar_fn;
  131. for (;;)
  132. {
  133. int cmp = (compar != NULL
  134. ? compar (node->value, elt)
  135. : (node->value > elt ? 1 :
  136. node->value < elt ? -1 : 0));
  137. if (cmp < 0)
  138. {
  139. if (node->right == NULL)
  140. {
  141. if (gl_tree_nx_add_after (set, node, elt) == NULL)
  142. return -1;
  143. return true;
  144. }
  145. node = node->right;
  146. }
  147. else if (cmp > 0)
  148. {
  149. if (node->left == NULL)
  150. {
  151. if (gl_tree_nx_add_before (set, node, elt) == NULL)
  152. return -1;
  153. return true;
  154. }
  155. node = node->left;
  156. }
  157. else /* cmp == 0 */
  158. return false;
  159. }
  160. }
  161. static bool
  162. gl_tree_remove (gl_oset_t set, const void *elt)
  163. {
  164. gl_oset_node_t node = gl_tree_search_node (set, elt);
  165. if (node != NULL)
  166. return gl_tree_remove_node (set, node);
  167. else
  168. return false;
  169. }
  170. static void
  171. gl_tree_oset_free (gl_oset_t set)
  172. {
  173. /* Iterate across all elements in post-order. */
  174. gl_oset_node_t node = set->root;
  175. iterstack_t stack;
  176. iterstack_item_t *stack_ptr = &stack[0];
  177. for (;;)
  178. {
  179. /* Descend on left branch. */
  180. for (;;)
  181. {
  182. if (node == NULL)
  183. break;
  184. stack_ptr->node = node;
  185. stack_ptr->rightp = false;
  186. node = node->left;
  187. stack_ptr++;
  188. }
  189. /* Climb up again. */
  190. for (;;)
  191. {
  192. if (stack_ptr == &stack[0])
  193. goto done_iterate;
  194. stack_ptr--;
  195. node = stack_ptr->node;
  196. if (!stack_ptr->rightp)
  197. break;
  198. /* Free the current node. */
  199. if (set->base.dispose_fn != NULL)
  200. set->base.dispose_fn (node->value);
  201. free (node);
  202. }
  203. /* Descend on right branch. */
  204. stack_ptr->rightp = true;
  205. node = node->right;
  206. stack_ptr++;
  207. }
  208. done_iterate:
  209. free (set);
  210. }
  211. /* --------------------- gl_oset_iterator_t Data Type --------------------- */
  212. static gl_oset_iterator_t
  213. gl_tree_iterator (gl_oset_t set)
  214. {
  215. gl_oset_iterator_t result;
  216. gl_oset_node_t node;
  217. result.vtable = set->base.vtable;
  218. result.set = set;
  219. /* Start node is the leftmost node. */
  220. node = set->root;
  221. if (node != NULL)
  222. while (node->left != NULL)
  223. node = node->left;
  224. result.p = node;
  225. /* End point is past the rightmost node. */
  226. result.q = NULL;
  227. #ifdef lint
  228. result.i = 0;
  229. result.j = 0;
  230. result.count = 0;
  231. #endif
  232. return result;
  233. }
  234. static bool
  235. gl_tree_iterator_next (gl_oset_iterator_t *iterator, const void **eltp)
  236. {
  237. if (iterator->p != iterator->q)
  238. {
  239. gl_oset_node_t node = (gl_oset_node_t) iterator->p;
  240. *eltp = node->value;
  241. /* Advance to the next node. */
  242. if (node->right != NULL)
  243. {
  244. node = node->right;
  245. while (node->left != NULL)
  246. node = node->left;
  247. }
  248. else
  249. {
  250. while (node->parent != NULL && node->parent->right == node)
  251. node = node->parent;
  252. node = node->parent;
  253. }
  254. iterator->p = node;
  255. return true;
  256. }
  257. else
  258. return false;
  259. }
  260. static void
  261. gl_tree_iterator_free (gl_oset_iterator_t *iterator)
  262. {
  263. }