interval_tree.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  1. /*!
  2. Temelia - Interval tree implementation source file.
  3. There are two ways to implement this data structure,
  4. with red-black trees and with some kind of heap. Because red-black tree is already
  5. implemented, here you can find the heap implementation of the interval tree.
  6. Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).
  7. @author Dascalu Laurentiu
  8. This program is free software; you can redistribute it and
  9. modify it under the terms of the GNU General Public License
  10. as published by the Free Software Foundation; either version 3
  11. of the License, or (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. #include "include/interval_tree.h"
  21. #include "include/queue.h"
  22. #include <string.h>
  23. struct _interval_node_t
  24. {
  25. int inf, sup;
  26. void *key;
  27. };
  28. struct _interval_tree_t
  29. {
  30. interval_tree_node_t *data;
  31. int size;
  32. };
  33. static interval_tree_t _interval_tree_new(int inf, int sup);
  34. static void _interval_node_add(interval_tree_t tree, int index, int inf, int sup);
  35. static void _interval_tree_preorder(interval_tree_t interval, int index,
  36. void key_handler(void *x, void *context), void *context);
  37. static void _interval_tree_inorder(interval_tree_t interval, int index,
  38. void key_handler(void *x, void *context), void *context);
  39. static void _interval_tree_reverse_inorder(interval_tree_t interval, int index,
  40. void key_handler(void *x, void *context), void *context);
  41. static void _interval_tree_postorder(interval_tree_t interval, int index,
  42. void key_handler(void *x, void *context), void *context);
  43. static void _interval_tree_show_indented(interval_tree_t interval, int index,
  44. void key_handler(void *key, int level, void *context), void *context,
  45. int level);
  46. /*
  47. * @brief Returns the smallest power of 2 such x <= power(2,k).
  48. */
  49. static int _next_power_2(int x);
  50. static void _interval_tree_insert(interval_tree_t interval_tree, int index,
  51. int inf, int sup, void *key);
  52. static void _interval_tree_search(interval_tree_t interval_tree, int index,
  53. int inf, int sup, void key_handler(void *key, void *context),
  54. void *context);
  55. interval_tree_node_t interval_tree_node_new(int inf, int sup, void *key)
  56. {
  57. interval_tree_node_t interval;
  58. interval = (struct _interval_node_t *) _new(sizeof(struct _interval_node_t));
  59. _ASSERT(interval, ==, NULL, NULL_POINTER, NULL);
  60. /*
  61. * Set the node's key, infinimum and supremum to given values.
  62. */
  63. interval->key = key;
  64. interval->inf = inf;
  65. interval->sup = sup;
  66. return interval;
  67. }
  68. void interval_tree_node_delete(interval_tree_node_t interval)
  69. {
  70. _ASSERT(interval, ==, NULL, NULL_POINTER,);
  71. interval->key = NULL;
  72. interval->inf = interval->sup = 0;
  73. _delete(interval);
  74. }
  75. int interval_tree_node_get_inf(interval_tree_node_t interval)
  76. {
  77. _ASSERT(interval, ==, NULL, NULL_POINTER, -1);
  78. return interval->inf;
  79. }
  80. int interval_tree_node_get_sup(interval_tree_node_t interval)
  81. {
  82. _ASSERT(interval, ==, NULL, NULL_POINTER, -1);
  83. return interval->sup;
  84. }
  85. void *interval_tree_node_get_key(interval_tree_node_t interval)
  86. {
  87. _ASSERT(interval, ==, NULL, NULL_POINTER, NULL);
  88. return interval->key;
  89. }
  90. interval_tree_t interval_tree_new(int inf, int sup)
  91. {
  92. _ASSERT(inf,>, sup, INVALID_INPUT, NULL);
  93. return _interval_tree_new(inf, sup);
  94. }
  95. void interval_tree_delete(interval_tree_t interval_tree)
  96. {
  97. int i = 0;
  98. _ASSERT(interval_tree, ==, NULL, NULL_POINTER,);
  99. for (; i < interval_tree->size; i++)
  100. interval_tree_node_delete(interval_tree->data[i]);
  101. _delete(interval_tree->data);
  102. _delete(interval_tree);
  103. }
  104. int interval_tree_is_empty(interval_tree_t interval_tree)
  105. {
  106. int i;
  107. _ASSERT(interval_tree, ==, NULL, NULL_POINTER, -1);
  108. /*
  109. * Check if the current node has non-NULL children pointers.
  110. */
  111. for (i = 0; i < interval_tree->size; i++)
  112. if (interval_tree->data[i] && interval_tree->data[i]->key)
  113. return 0;
  114. return 1;
  115. }
  116. interval_tree_node_t *interval_tree_get_data(interval_tree_t interval_tree)
  117. {
  118. _ASSERT(interval_tree, ==, NULL, NULL_POINTER, NULL);
  119. return interval_tree->data;
  120. }
  121. int interval_tree_get_size(interval_tree_t interval_tree)
  122. {
  123. _ASSERT(interval_tree, ==, NULL, NULL_POINTER, -1);
  124. return interval_tree->size;
  125. }
  126. void interval_tree_search(interval_tree_t interval_tree, int inf, int sup,
  127. void key_handler(void *key, void *context), void *context)
  128. {
  129. _ASSERT(interval_tree, ==, NULL, NULL_POINTER,);
  130. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  131. _ASSERT(sup,>, interval_tree->data[0]->sup, INVALID_INPUT,);
  132. _ASSERT(inf, <, interval_tree->data[0]->inf, INVALID_INPUT,);
  133. /*
  134. * The algorithm is :
  135. * search (node, left, right, inf, sup)
  136. * {
  137. * if (inf <= left && right <= sup)
  138. * callback function (key stored in current node)
  139. * else
  140. * let mid be (left+right)/2
  141. * if (inf <= mid)
  142. * search(left node, left, mid, inf, sup);
  143. * if (sup >= mid+1)
  144. * search(right node, mid + 1, right, inf, sup);
  145. * callback function (key stored in current node)
  146. * }
  147. */
  148. _interval_tree_search(interval_tree, 0, inf, sup, key_handler, context);
  149. }
  150. void interval_tree_insert(interval_tree_t interval_tree, int inf, int sup,
  151. void *key)
  152. {
  153. _ASSERT(interval_tree, ==, NULL, NULL_POINTER,);
  154. _ASSERT(sup,>, interval_tree->data[0]->sup, INVALID_INPUT,);
  155. _ASSERT(inf, <, interval_tree->data[0]->inf, INVALID_INPUT,);
  156. /* The algorithm is :
  157. * search (node, left, right, inf, sup)
  158. * {
  159. * if (inf <= left && right <= sup)
  160. * change key's value, stored in current node, to new key
  161. * else
  162. * let mid be (left+right)/2
  163. * if (inf <= mid)
  164. * search(left node, left, mid, inf, sup);
  165. * if (sup >= mid+1)
  166. * search(right node, mid + 1, right, inf, sup);
  167. * change key's value, stored in current node, to new key
  168. */
  169. _interval_tree_insert(interval_tree, 0, inf, sup, key);
  170. }
  171. void interval_tree_remove(interval_tree_t interval_tree, int inf, int sup)
  172. {
  173. interval_tree_insert(interval_tree, inf, sup, NULL);
  174. }
  175. interval_tree_node_t interval_tree_get_node(interval_tree_t interval_tree, int index)
  176. {
  177. _ASSERT(interval_tree, ==, NULL, NULL_POINTER, NULL);
  178. _ASSERT(index, <, 0, INVALID_INPUT, NULL);
  179. _ASSERT(index,>, interval_tree->size, INVALID_INPUT, NULL);
  180. return interval_tree->data[index];
  181. }
  182. void interval_tree_preorder(interval_tree_t interval, void key_handler(void *x,
  183. void *context), void *context)
  184. {
  185. _ASSERT(interval, ==, NULL, NULL_POINTER,);
  186. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  187. _interval_tree_preorder(interval, 0, key_handler, context);
  188. }
  189. void interval_tree_inorder(interval_tree_t interval, void key_handler(void *x,
  190. void *context), void *context)
  191. {
  192. _ASSERT(interval, ==, NULL, NULL_POINTER,);
  193. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  194. _interval_tree_inorder(interval, 0, key_handler, context);
  195. }
  196. void interval_tree_reverse_inorder(interval_tree_t interval, void key_handler(
  197. void *x, void *context), void *context)
  198. {
  199. _ASSERT(interval, ==, NULL, NULL_POINTER,);
  200. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  201. _interval_tree_reverse_inorder(interval, 0, key_handler, context);
  202. }
  203. void interval_tree_postorder(interval_tree_t interval, void key_handler(void *x,
  204. void *context), void *context)
  205. {
  206. _ASSERT(interval, ==, NULL, NULL_POINTER,);
  207. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  208. _interval_tree_postorder(interval, 0, key_handler, context);
  209. }
  210. void interval_tree_level_order(interval_tree_t interval, void key_handler(
  211. void *x, void *context), void *context)
  212. {
  213. queue_t Q = queue_new(DEFAULT_SIZE);
  214. int *current_node, *aux, node;
  215. aux = (int *) _new(sizeof(int));
  216. *aux = 0;
  217. queue_push_back(Q, aux);
  218. while (!queue_is_empty(Q))
  219. {
  220. current_node = queue_get_front(Q);
  221. queue_pop_front(Q);
  222. key_handler(interval->data[*current_node]->key, context);
  223. node = 2 * (*current_node) + 1;
  224. if (node < interval->size && interval->data[node])
  225. {
  226. aux = (int *) _new(sizeof(int));
  227. *aux = node;
  228. queue_push_back(Q, aux);
  229. }
  230. node++;
  231. if (node < interval->size && interval->data[node])
  232. {
  233. aux = (int *) _new(sizeof(int));
  234. *aux = node;
  235. queue_push_back(Q, aux);
  236. }
  237. _delete(current_node);
  238. }
  239. queue_delete(Q);
  240. }
  241. void interval_tree_show_indented(interval_tree_t interval, void key_handler(
  242. void *x, int level, void *context), void *context)
  243. {
  244. _ASSERT(interval, ==, NULL, NULL_POINTER,);
  245. _ASSERT(key_handler, ==, NULL, NULL_POINTER,);
  246. _interval_tree_show_indented(interval, 0, key_handler, context, 0);
  247. }
  248. static void _interval_node_add(interval_tree_t tree, int index, int inf, int sup)
  249. {
  250. tree->data[index] = interval_tree_node_new(inf, sup, NULL);
  251. if (inf < sup)
  252. {
  253. _interval_node_add(tree, 2 * index + 1, inf, (inf + sup) / 2);
  254. _interval_node_add(tree, 2 * index + 2, (inf + sup) / 2 + 1, sup);
  255. }
  256. }
  257. static interval_tree_t _interval_tree_new(int inf, int sup)
  258. {
  259. interval_tree_t tree;
  260. tree = (struct _interval_tree_t *) _new(sizeof(struct _interval_tree_t));
  261. _ASSERT(tree, ==, NULL, NULL_POINTER, NULL);
  262. tree->size = 2 * _next_power_2(sup - inf + 1) - 1;
  263. tree->data = (interval_tree_node_t *) _new(tree->size * sizeof(interval_tree_node_t));
  264. memset(tree->data, 0, tree->size * sizeof(interval_tree_node_t));
  265. _ASSERT(tree->data, ==, NULL, NULL_POINTER, NULL);
  266. _interval_node_add(tree, 0, inf, sup);
  267. return tree;
  268. }
  269. static void _interval_tree_preorder(interval_tree_t interval, int index,
  270. void key_handler(void *x, void *context), void *context)
  271. {
  272. if (index < interval->size)
  273. {
  274. if (interval->data[index])
  275. key_handler(interval->data[index]->key, context);
  276. _interval_tree_preorder(interval, 2 * index + 1, key_handler, context);
  277. _interval_tree_preorder(interval, 2 * index + 2, key_handler, context);
  278. }
  279. }
  280. static void _interval_tree_inorder(interval_tree_t interval, int index,
  281. void key_handler(void *x, void *context), void *context)
  282. {
  283. if (index < interval->size)
  284. {
  285. _interval_tree_inorder(interval, 2 * index + 1, key_handler, context);
  286. if (interval->data[index])
  287. key_handler(interval->data[index]->key, context);
  288. _interval_tree_inorder(interval, 2 * index + 2, key_handler, context);
  289. }
  290. }
  291. static void _interval_tree_reverse_inorder(interval_tree_t interval, int index,
  292. void key_handler(void *x, void *context), void *context)
  293. {
  294. if (index < interval->size)
  295. {
  296. _interval_tree_inorder(interval, 2 * index + 2, key_handler, context);
  297. if (interval->data[index])
  298. key_handler(interval->data[index]->key, context);
  299. _interval_tree_inorder(interval, 2 * index + 1, key_handler, context);
  300. }
  301. }
  302. static void _interval_tree_postorder(interval_tree_t interval, int index,
  303. void key_handler(void *x, void *context), void *context)
  304. {
  305. if (index < interval->size)
  306. {
  307. _interval_tree_inorder(interval, 2 * index + 1, key_handler, context);
  308. _interval_tree_inorder(interval, 2 * index + 2, key_handler, context);
  309. if (interval->data[index])
  310. key_handler(interval->data[index]->key, context);
  311. }
  312. }
  313. void _interval_tree_show_indented(interval_tree_t interval, int index,
  314. void key_handler(void *key, int level, void *context), void *context,
  315. int level)
  316. {
  317. if (index < interval->size)
  318. {
  319. _interval_tree_show_indented(interval, 2 * index + 2, key_handler,
  320. context, level + 1);
  321. if (interval->data[index])
  322. key_handler(interval->data[index]->key, level, context);
  323. _interval_tree_show_indented(interval, 2 * index + 1, key_handler,
  324. context, level + 1);
  325. }
  326. }
  327. static int _next_power_2(int x)
  328. {
  329. int ok = 1;
  330. int y = 1;
  331. if (x == 0)
  332. return 1;
  333. while (x > 1)
  334. {
  335. if (x % 2 == 1)
  336. ok = 0;
  337. y *= 2;
  338. x /= 2;
  339. }
  340. if (!ok)
  341. y *= 2;
  342. return y;
  343. }
  344. static void _interval_tree_insert(interval_tree_t interval_tree, int index,
  345. int inf, int sup, void *key)
  346. {
  347. int _inf = 0, _sup = 0, _mid = 0;
  348. if (index >= interval_tree->size || interval_tree->data[index] == NULL)
  349. return;
  350. _inf = interval_tree->data[index]->inf;
  351. _sup = interval_tree->data[index]->sup;
  352. if (inf <= _inf && _sup <= sup)
  353. interval_tree->data[index]->key = key;
  354. else
  355. {
  356. _mid = (_inf + _sup) / 2;
  357. if (inf <= _mid)
  358. _interval_tree_insert(interval_tree, 2 * index + 1, inf, sup, key);
  359. if (sup >= _mid + 1)
  360. _interval_tree_insert(interval_tree, 2 * index + 2, inf, sup, key);
  361. interval_tree->data[index]->key = key;
  362. }
  363. }
  364. static void _interval_tree_search(interval_tree_t interval_tree, int index,
  365. int inf, int sup, void key_handler(void *key, void *context),
  366. void *context)
  367. {
  368. int _inf = 0, _sup = 0, _mid = 0;
  369. if (index >= interval_tree->size || interval_tree->data[index] == NULL)
  370. return;
  371. _inf = interval_tree->data[index]->inf;
  372. _sup = interval_tree->data[index]->sup;
  373. if (inf <= _inf && _sup <= sup)
  374. key_handler(interval_tree->data[index]->key, context);
  375. else
  376. {
  377. _mid = _inf + (_sup - _inf) / 2;
  378. if (inf <= _mid)
  379. _interval_tree_search(interval_tree, 2 * index + 1, inf, sup,
  380. key_handler, context);
  381. if (sup >= _mid + 1)
  382. _interval_tree_search(interval_tree, 2 * index + 2, inf, sup,
  383. key_handler, context);
  384. key_handler(interval_tree->data[index]->key, context);
  385. }
  386. }