tree.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. /*!
  2. Temelia - Multipath tree implementation source file.
  3. Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).
  4. @author Dascalu Laurentiu
  5. This program is free software; you can redistribute it and
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 3
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16. */
  17. #include "include/common.h"
  18. #include "include/linked_list.h"
  19. #include "include/vector.h"
  20. #include "include/tree.h"
  21. #include <stdlib.h>
  22. struct _tree_node_t
  23. {
  24. /*! user's key */
  25. void *key;
  26. /*! reference to parent */
  27. struct _tree_node_t *parent;
  28. /*! vector/linked list of references to children */
  29. void *children;
  30. /*! tree backbone type */
  31. int var_children_size;
  32. };
  33. static void _tree_delete_handler(void *key, void *context);
  34. tree_t tree_new(void *key, int var_children_size)
  35. {
  36. tree_t tree;
  37. LOGGER("[tree new] key=\"%p\" var_children_size=\"%d\"\n", key,
  38. var_children_size);
  39. tree = (struct _tree_node_t *) _new(sizeof(struct _tree_node_t));
  40. _ASSERT(tree, ==, NULL, NULL_POINTER, NULL);
  41. LOGGER("[tree new] tree=\"%p\"\n", tree);
  42. if (var_children_size)
  43. {
  44. tree->children = linked_list_new();
  45. LOGGER("[tree new] linked list tree->children=\"%p\"\n", tree->children);
  46. }
  47. else
  48. {
  49. tree->children = vector_new(DEFAULT_SIZE);
  50. LOGGER("[tree new] vector tree->children=\"%p\"\n", tree->children);
  51. }
  52. // If memory allocation failed return NULL.
  53. if (tree->children == NULL)
  54. {
  55. LOGGER("[tree new] children memory allocation failed\n");
  56. _delete(tree);
  57. return NULL;
  58. }
  59. tree->key = key;
  60. tree->parent = NULL;
  61. tree->var_children_size = var_children_size;
  62. return tree;
  63. }
  64. void tree_delete_node(tree_t node)
  65. {
  66. LOGGER("[tree delete node] node=\"%p\"\n", node);
  67. _ASSERT(node, ==, NULL, NULL_POINTER,);
  68. node->key = NULL;
  69. node->parent = NULL;
  70. if (node->var_children_size)
  71. linked_list_delete(node->children);
  72. else
  73. vector_delete(node->children);
  74. _delete(node);
  75. }
  76. void tree_delete(tree_t tree)
  77. {
  78. LOGGER("[tree delete] tree=\"%p\"\n", tree);
  79. _ASSERT(tree, ==, NULL, NULL_POINTER,);
  80. if (tree->var_children_size)
  81. linked_list_iterate(tree->children, _tree_delete_handler, NULL, 1);
  82. else
  83. vector_iterate(tree->children, _tree_delete_handler, NULL);
  84. tree_delete_node(tree);
  85. }
  86. int tree_get_type(tree_t tree)
  87. {
  88. LOGGER("[tree get type] tree=\"%p\"\n", tree);
  89. _ASSERT(tree, ==, NULL, NULL_POINTER, -1);
  90. return tree->var_children_size;
  91. }
  92. void tree_set_type(tree_t tree, int variable_children)
  93. {
  94. LOGGER("[tree set type] tree=\"%p\" variable_children=\"%d\"\n", tree,
  95. variable_children);
  96. _ASSERT(tree, ==, NULL, NULL_POINTER,);
  97. tree->var_children_size = variable_children;
  98. }
  99. void tree_set_key(tree_t node, void *key)
  100. {
  101. LOGGER("[tree set key] node=\"%p\" key=\"%p\"\n", node, key);
  102. _ASSERT(node, ==, NULL, NULL_POINTER,);
  103. node->key = key;
  104. }
  105. void *tree_get_key(tree_t node)
  106. {
  107. LOGGER("[tree get key] node=\"%p\" key=\"%p\"\n", node, node->key);
  108. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  109. return node->key;
  110. }
  111. tree_t tree_get_parent(tree_t node)
  112. {
  113. LOGGER("[tree get parent] node=\"%p\" parent=\"%p\"\n", node, node->parent);
  114. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  115. return node->parent;
  116. }
  117. void tree_set_parent(tree_t parent, tree_t child)
  118. {
  119. int added;
  120. LOGGER("[tree set parent] parent=\"%p\" child=\"%p\"\n", parent, child);
  121. _ASSERT(parent, ==, NULL, NULL_POINTER,);
  122. _ASSERT(child, ==, NULL, NULL_POINTER,);
  123. child->parent = parent;
  124. added = 0;
  125. if (parent->var_children_size)
  126. {
  127. if (linked_list_search_key(parent->children, child, compare_pointers,
  128. NULL) == NULL)
  129. {
  130. linked_list_push_back(parent->children, child);
  131. added = 1;
  132. }
  133. }
  134. else
  135. {
  136. if (vector_search(parent->children, child, compare_pointers, NULL)
  137. == -1)
  138. {
  139. vector_push_back(parent->children, child);
  140. added = 1;
  141. }
  142. }
  143. LOGGER("[tree set parent] ");
  144. if (added)
  145. LOGGER("added child to");
  146. else
  147. LOGGER("child already exists into the");
  148. LOGGER(" parent children list/vector\n");
  149. LOGGER("[tree set parent] successfully finished");
  150. }
  151. void tree_add_child(tree_t node, tree_t child)
  152. {
  153. LOGGER("[tree add child] node=\"%p\" child=\"%p\"\n", node, child);
  154. _ASSERT(node, ==, NULL, NULL_POINTER,);
  155. _ASSERT(child, ==, NULL, NULL_POINTER,);
  156. child->parent = node;
  157. if (node->var_children_size)
  158. linked_list_push_back(node->children, child);
  159. else
  160. vector_push_back(node->children, child);
  161. }
  162. tree_t tree_remove_child(tree_t node, int index)
  163. {
  164. tree_t child;
  165. LOGGER("[tree remove child] node=\"%p\" index=\"%d\"\n", node, index);
  166. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  167. _ASSERT(index, <, 0, INVALID_INPUT, NULL);
  168. if (node->var_children_size)
  169. _ASSERT(index, >=, linked_list_get_size(node->children), INVALID_INPUT, NULL);
  170. else
  171. _ASSERT(index, >=, vector_get_size(node->children), INVALID_INPUT, NULL);
  172. if (node->var_children_size)
  173. {
  174. child = linked_list_get_key_at(node->children, index);
  175. linked_list_remove_key(node->children, child, compare_pointers, NULL, 1);
  176. }
  177. else
  178. child = vector_remove_key_at(node->children, index);
  179. _ASSERT(child, ==, NULL, NULL_POINTER, NULL);
  180. child->parent = NULL;
  181. return child;
  182. }
  183. void tree_remove_from_parent(tree_t node)
  184. {
  185. tree_t parent;
  186. LOGGER("[tree remove from parent] node=\"%p\"\n", node);
  187. _ASSERT(node, ==, NULL, NULL_POINTER,);
  188. parent = node->parent;
  189. node->parent = NULL;
  190. if (node->var_children_size)
  191. linked_list_remove_key(parent->children, node, compare_pointers, NULL,
  192. 1);
  193. else
  194. vector_remove_key(parent->children, node, compare_pointers, NULL);
  195. }
  196. void *tree_get_children(tree_t node)
  197. {
  198. LOGGER("[tree get children] internal_representation=\"%p\"\n", node);
  199. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  200. return node->children;
  201. }
  202. int tree_get_children_number(tree_t node)
  203. {
  204. LOGGER("[tree get children number] node=\"%p\"\n", node);
  205. _ASSERT(node, ==, NULL, NULL_POINTER, -1);
  206. if (node->var_children_size)
  207. return linked_list_get_size(node->children);
  208. return vector_get_size(node->children);
  209. }
  210. tree_t tree_get_child(tree_t node, int index)
  211. {
  212. LOGGER("[tree get child] node=\"%p\" index=\"%d\"\n", node, index);
  213. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  214. _ASSERT(index, <, 0, INVALID_INPUT, NULL);
  215. if (node->var_children_size)
  216. _ASSERT(index, >=, linked_list_get_size(node->children), INVALID_INPUT, NULL);
  217. else
  218. _ASSERT(index, >=, vector_get_size(node->children), INVALID_INPUT, NULL);
  219. if (node->var_children_size)
  220. return linked_list_get_key_at(node->children, index);
  221. return vector_get_key_at(node->children, index);
  222. }
  223. int tree_is_empty(tree_t node)
  224. {
  225. LOGGER("[tree is empty] node=\"%p\"\n", node);
  226. _ASSERT(node, ==, NULL, NULL_POINTER, -1);
  227. if (node->parent == NULL && node->key == NULL)
  228. {
  229. if (node->var_children_size)
  230. return linked_list_get_size(node->children) == 0;
  231. return vector_get_size(node->children) == 0;
  232. }
  233. return 0;
  234. }
  235. int tree_is_leaf(tree_t node)
  236. {
  237. LOGGER("[tree is leaf] node=\"%p\"\n", node);
  238. _ASSERT(node, ==, NULL, NULL_POINTER, -1);
  239. if (node->var_children_size)
  240. return linked_list_get_size(node->children) == 0;
  241. return vector_get_size(node->children) == 0;
  242. }
  243. int tree_get_height(tree_t node)
  244. {
  245. int max_height, height, i;
  246. void *it;
  247. LOGGER("[tree get height] node=\"%p\"\n", node);
  248. _ASSERT(node, ==, NULL, NULL_POINTER, -1);
  249. max_height = 0;
  250. if (node->var_children_size)
  251. {
  252. if (linked_list_get_size(node->children) == 0)
  253. return 0;
  254. // Find the child with the maximum height.
  255. for (it = linked_list_get_begin(node->children); it != NULL; it
  256. = linked_list_iterator_get_next(it))
  257. {
  258. height = tree_get_height(linked_list_iterator_get_key(it));
  259. max_height = MAX(max_height, height);
  260. }
  261. }
  262. else
  263. {
  264. if (vector_get_size(node->children) == 0)
  265. return 0;
  266. for (i = 0; i < vector_get_size(node->children); i++)
  267. {
  268. height = tree_get_height(vector_get_key_at(node->children, i));
  269. max_height = MAX(max_height, height);
  270. }
  271. }
  272. return 1 + max_height;
  273. }
  274. tree_t tree_get_root(tree_t node)
  275. {
  276. LOGGER("[tree get root] node=\"%p\"\n", node);
  277. _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
  278. while (node->parent != NULL)
  279. node = node->parent;
  280. return node;
  281. }
  282. int tree_get_size(tree_t tree)
  283. {
  284. int tree_size, i;
  285. linked_list_iterator_t it;
  286. LOGGER("[tree get size] tree=\"%p\"\n", tree);
  287. _ASSERT(tree, ==, NULL, NULL_POINTER, -1);
  288. tree_size = 0;
  289. if (tree->var_children_size)
  290. {
  291. if (linked_list_get_size(tree->children) == 0)
  292. return 1;
  293. for (it = linked_list_get_begin(tree->children); it != NULL; it
  294. = linked_list_iterator_get_next(it))
  295. tree_size += tree_get_size(linked_list_iterator_get_key(it));
  296. }
  297. else
  298. {
  299. if (vector_get_size(tree->children) == 0)
  300. return 1;
  301. for (i = 0; i < vector_get_size(tree->children); i++)
  302. tree_size += tree_get_size(vector_get_key_at(tree->children, i));
  303. }
  304. return tree_size + 1;
  305. }
  306. void _tree_delete_handler(void *key, void *context)
  307. {
  308. tree_delete(key);
  309. }