123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417 |
- /*!
- Temelia - Multipath tree implementation source file.
- Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia).
- @author Dascalu Laurentiu
- This program is free software; you can redistribute it and
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 3
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
- #include "include/common.h"
- #include "include/linked_list.h"
- #include "include/vector.h"
- #include "include/tree.h"
- #include <stdlib.h>
- struct _tree_node_t
- {
- /*! user's key */
- void *key;
- /*! reference to parent */
- struct _tree_node_t *parent;
- /*! vector/linked list of references to children */
- void *children;
- /*! tree backbone type */
- int var_children_size;
- };
- static void _tree_delete_handler(void *key, void *context);
- tree_t tree_new(void *key, int var_children_size)
- {
- tree_t tree;
- LOGGER("[tree new] key=\"%p\" var_children_size=\"%d\"\n", key,
- var_children_size);
- tree = (struct _tree_node_t *) _new(sizeof(struct _tree_node_t));
- _ASSERT(tree, ==, NULL, NULL_POINTER, NULL);
- LOGGER("[tree new] tree=\"%p\"\n", tree);
- if (var_children_size)
- {
- tree->children = linked_list_new();
- LOGGER("[tree new] linked list tree->children=\"%p\"\n", tree->children);
- }
- else
- {
- tree->children = vector_new(DEFAULT_SIZE);
- LOGGER("[tree new] vector tree->children=\"%p\"\n", tree->children);
- }
- // If memory allocation failed return NULL.
- if (tree->children == NULL)
- {
- LOGGER("[tree new] children memory allocation failed\n");
- _delete(tree);
- return NULL;
- }
- tree->key = key;
- tree->parent = NULL;
- tree->var_children_size = var_children_size;
- return tree;
- }
- void tree_delete_node(tree_t node)
- {
- LOGGER("[tree delete node] node=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER,);
- node->key = NULL;
- node->parent = NULL;
- if (node->var_children_size)
- linked_list_delete(node->children);
- else
- vector_delete(node->children);
- _delete(node);
- }
- void tree_delete(tree_t tree)
- {
- LOGGER("[tree delete] tree=\"%p\"\n", tree);
- _ASSERT(tree, ==, NULL, NULL_POINTER,);
- if (tree->var_children_size)
- linked_list_iterate(tree->children, _tree_delete_handler, NULL, 1);
- else
- vector_iterate(tree->children, _tree_delete_handler, NULL);
- tree_delete_node(tree);
- }
- int tree_get_type(tree_t tree)
- {
- LOGGER("[tree get type] tree=\"%p\"\n", tree);
- _ASSERT(tree, ==, NULL, NULL_POINTER, -1);
- return tree->var_children_size;
- }
- void tree_set_type(tree_t tree, int variable_children)
- {
- LOGGER("[tree set type] tree=\"%p\" variable_children=\"%d\"\n", tree,
- variable_children);
- _ASSERT(tree, ==, NULL, NULL_POINTER,);
- tree->var_children_size = variable_children;
- }
- void tree_set_key(tree_t node, void *key)
- {
- LOGGER("[tree set key] node=\"%p\" key=\"%p\"\n", node, key);
- _ASSERT(node, ==, NULL, NULL_POINTER,);
- node->key = key;
- }
- void *tree_get_key(tree_t node)
- {
- LOGGER("[tree get key] node=\"%p\" key=\"%p\"\n", node, node->key);
- _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
- return node->key;
- }
- tree_t tree_get_parent(tree_t node)
- {
- LOGGER("[tree get parent] node=\"%p\" parent=\"%p\"\n", node, node->parent);
- _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
- return node->parent;
- }
- void tree_set_parent(tree_t parent, tree_t child)
- {
- int added;
- LOGGER("[tree set parent] parent=\"%p\" child=\"%p\"\n", parent, child);
- _ASSERT(parent, ==, NULL, NULL_POINTER,);
- _ASSERT(child, ==, NULL, NULL_POINTER,);
- child->parent = parent;
- added = 0;
- if (parent->var_children_size)
- {
- if (linked_list_search_key(parent->children, child, compare_pointers,
- NULL) == NULL)
- {
- linked_list_push_back(parent->children, child);
- added = 1;
- }
- }
- else
- {
- if (vector_search(parent->children, child, compare_pointers, NULL)
- == -1)
- {
- vector_push_back(parent->children, child);
- added = 1;
- }
- }
- LOGGER("[tree set parent] ");
- if (added)
- LOGGER("added child to");
- else
- LOGGER("child already exists into the");
- LOGGER(" parent children list/vector\n");
- LOGGER("[tree set parent] successfully finished");
- }
- void tree_add_child(tree_t node, tree_t child)
- {
- LOGGER("[tree add child] node=\"%p\" child=\"%p\"\n", node, child);
- _ASSERT(node, ==, NULL, NULL_POINTER,);
- _ASSERT(child, ==, NULL, NULL_POINTER,);
- child->parent = node;
- if (node->var_children_size)
- linked_list_push_back(node->children, child);
- else
- vector_push_back(node->children, child);
- }
- tree_t tree_remove_child(tree_t node, int index)
- {
- tree_t child;
- LOGGER("[tree remove child] node=\"%p\" index=\"%d\"\n", node, index);
- _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
- _ASSERT(index, <, 0, INVALID_INPUT, NULL);
- if (node->var_children_size)
- _ASSERT(index, >=, linked_list_get_size(node->children), INVALID_INPUT, NULL);
- else
- _ASSERT(index, >=, vector_get_size(node->children), INVALID_INPUT, NULL);
- if (node->var_children_size)
- {
- child = linked_list_get_key_at(node->children, index);
- linked_list_remove_key(node->children, child, compare_pointers, NULL, 1);
- }
- else
- child = vector_remove_key_at(node->children, index);
- _ASSERT(child, ==, NULL, NULL_POINTER, NULL);
- child->parent = NULL;
- return child;
- }
- void tree_remove_from_parent(tree_t node)
- {
- tree_t parent;
- LOGGER("[tree remove from parent] node=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER,);
- parent = node->parent;
- node->parent = NULL;
- if (node->var_children_size)
- linked_list_remove_key(parent->children, node, compare_pointers, NULL,
- 1);
- else
- vector_remove_key(parent->children, node, compare_pointers, NULL);
- }
- void *tree_get_children(tree_t node)
- {
- LOGGER("[tree get children] internal_representation=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
- return node->children;
- }
- int tree_get_children_number(tree_t node)
- {
- LOGGER("[tree get children number] node=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER, -1);
- if (node->var_children_size)
- return linked_list_get_size(node->children);
- return vector_get_size(node->children);
- }
- tree_t tree_get_child(tree_t node, int index)
- {
- LOGGER("[tree get child] node=\"%p\" index=\"%d\"\n", node, index);
- _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
- _ASSERT(index, <, 0, INVALID_INPUT, NULL);
- if (node->var_children_size)
- _ASSERT(index, >=, linked_list_get_size(node->children), INVALID_INPUT, NULL);
- else
- _ASSERT(index, >=, vector_get_size(node->children), INVALID_INPUT, NULL);
- if (node->var_children_size)
- return linked_list_get_key_at(node->children, index);
- return vector_get_key_at(node->children, index);
- }
- int tree_is_empty(tree_t node)
- {
- LOGGER("[tree is empty] node=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER, -1);
- if (node->parent == NULL && node->key == NULL)
- {
- if (node->var_children_size)
- return linked_list_get_size(node->children) == 0;
- return vector_get_size(node->children) == 0;
- }
- return 0;
- }
- int tree_is_leaf(tree_t node)
- {
- LOGGER("[tree is leaf] node=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER, -1);
- if (node->var_children_size)
- return linked_list_get_size(node->children) == 0;
- return vector_get_size(node->children) == 0;
- }
- int tree_get_height(tree_t node)
- {
- int max_height, height, i;
- void *it;
- LOGGER("[tree get height] node=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER, -1);
- max_height = 0;
- if (node->var_children_size)
- {
- if (linked_list_get_size(node->children) == 0)
- return 0;
- // Find the child with the maximum height.
- for (it = linked_list_get_begin(node->children); it != NULL; it
- = linked_list_iterator_get_next(it))
- {
- height = tree_get_height(linked_list_iterator_get_key(it));
- max_height = MAX(max_height, height);
- }
- }
- else
- {
- if (vector_get_size(node->children) == 0)
- return 0;
- for (i = 0; i < vector_get_size(node->children); i++)
- {
- height = tree_get_height(vector_get_key_at(node->children, i));
- max_height = MAX(max_height, height);
- }
- }
- return 1 + max_height;
- }
- tree_t tree_get_root(tree_t node)
- {
- LOGGER("[tree get root] node=\"%p\"\n", node);
- _ASSERT(node, ==, NULL, NULL_POINTER, NULL);
- while (node->parent != NULL)
- node = node->parent;
- return node;
- }
- int tree_get_size(tree_t tree)
- {
- int tree_size, i;
- linked_list_iterator_t it;
- LOGGER("[tree get size] tree=\"%p\"\n", tree);
- _ASSERT(tree, ==, NULL, NULL_POINTER, -1);
- tree_size = 0;
- if (tree->var_children_size)
- {
- if (linked_list_get_size(tree->children) == 0)
- return 1;
- for (it = linked_list_get_begin(tree->children); it != NULL; it
- = linked_list_iterator_get_next(it))
- tree_size += tree_get_size(linked_list_iterator_get_key(it));
- }
- else
- {
- if (vector_get_size(tree->children) == 0)
- return 1;
- for (i = 0; i < vector_get_size(tree->children); i++)
- tree_size += tree_get_size(vector_get_key_at(tree->children, i));
- }
- return tree_size + 1;
- }
- void _tree_delete_handler(void *key, void *context)
- {
- tree_delete(key);
- }
|