1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * SPDX-License-Identifier: LGPL-2.1-or-later
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
36 #include "gtestutils.h"
40 * SECTION:trees-binary
41 * @title: Balanced Binary Trees
42 * @short_description: a sorted collection of key/value pairs optimized
43 * for searching and traversing in order
45 * The #GTree structure and its associated functions provide a sorted
46 * collection of key/value pairs optimized for searching and traversing
47 * in order. This means that most of the operations (access, search,
48 * insertion, deletion, ...) on #GTree are O(log(n)) in average and O(n)
49 * in worst case for time complexity. But, note that maintaining a
50 * balanced sorted #GTree of n elements is done in time O(n log(n)).
52 * To create a new #GTree use g_tree_new().
54 * To insert a key/value pair into a #GTree use g_tree_insert()
57 * To remove a key/value pair use g_tree_remove() (O(n log(n))).
59 * To look up the value corresponding to a given key, use
60 * g_tree_lookup() and g_tree_lookup_extended().
62 * To find out the number of nodes in a #GTree, use g_tree_nnodes(). To
63 * get the height of a #GTree, use g_tree_height().
65 * To traverse a #GTree, calling a function for each node visited in
66 * the traversal, use g_tree_foreach().
68 * To destroy a #GTree, use g_tree_destroy().
71 #define MAX_GTREE_HEIGHT 40
72 /* G_MAXUINT nodes will be covered by tree height of log2(G_MAXUINT) + 2. */
73 G_STATIC_ASSERT ((G_GUINT64_CONSTANT (1) << (MAX_GTREE_HEIGHT - 2)) >= G_MAXUINT);
78 * The GTree struct is an opaque data structure representing a
79 * [balanced binary tree][glib-Balanced-Binary-Trees]. It should be
80 * accessed only by using the following functions.
85 GCompareDataFunc key_compare;
86 GDestroyNotify key_destroy_func;
87 GDestroyNotify value_destroy_func;
88 gpointer key_compare_data;
95 gpointer key; /* key for this node */
96 gpointer value; /* value stored at this node */
97 GTreeNode *left; /* left subtree */
98 GTreeNode *right; /* right subtree */
99 gint8 balance; /* height (right) - height (left) */
105 static GTreeNode* g_tree_node_new (gpointer key,
107 static GTreeNode *g_tree_insert_internal (GTree *tree,
111 gboolean null_ret_ok);
112 static gboolean g_tree_remove_internal (GTree *tree,
115 static GTreeNode* g_tree_node_balance (GTreeNode *node);
116 static GTreeNode *g_tree_find_node (GTree *tree,
118 static gint g_tree_node_pre_order (GTreeNode *node,
119 GTraverseFunc traverse_func,
121 static gint g_tree_node_in_order (GTreeNode *node,
122 GTraverseFunc traverse_func,
124 static gint g_tree_node_post_order (GTreeNode *node,
125 GTraverseFunc traverse_func,
127 static GTreeNode *g_tree_node_search (GTreeNode *node,
128 GCompareFunc search_func,
130 static GTreeNode* g_tree_node_rotate_left (GTreeNode *node);
131 static GTreeNode* g_tree_node_rotate_right (GTreeNode *node);
133 static void g_tree_node_check (GTreeNode *node);
138 g_tree_node_new (gpointer key,
141 GTreeNode *node = g_slice_new (GTreeNode);
146 node->left_child = FALSE;
147 node->right_child = FALSE;
156 * @key_compare_func: the function used to order the nodes in the #GTree.
157 * It should return values similar to the standard strcmp() function -
158 * 0 if the two arguments are equal, a negative value if the first argument
159 * comes before the second, or a positive value if the first argument comes
162 * Creates a new #GTree.
164 * Returns: a newly allocated #GTree
167 g_tree_new (GCompareFunc key_compare_func)
169 g_return_val_if_fail (key_compare_func != NULL, NULL);
171 return g_tree_new_full ((GCompareDataFunc) key_compare_func, NULL,
176 * g_tree_new_with_data:
177 * @key_compare_func: qsort()-style comparison function
178 * @key_compare_data: data to pass to comparison function
180 * Creates a new #GTree with a comparison function that accepts user data.
181 * See g_tree_new() for more details.
183 * Returns: a newly allocated #GTree
186 g_tree_new_with_data (GCompareDataFunc key_compare_func,
187 gpointer key_compare_data)
189 g_return_val_if_fail (key_compare_func != NULL, NULL);
191 return g_tree_new_full (key_compare_func, key_compare_data,
197 * @key_compare_func: qsort()-style comparison function
198 * @key_compare_data: data to pass to comparison function
199 * @key_destroy_func: a function to free the memory allocated for the key
200 * used when removing the entry from the #GTree or %NULL if you don't
201 * want to supply such a function
202 * @value_destroy_func: a function to free the memory allocated for the
203 * value used when removing the entry from the #GTree or %NULL if you
204 * don't want to supply such a function
206 * Creates a new #GTree like g_tree_new() and allows to specify functions
207 * to free the memory allocated for the key and value that get called when
208 * removing the entry from the #GTree.
210 * Returns: a newly allocated #GTree
213 g_tree_new_full (GCompareDataFunc key_compare_func,
214 gpointer key_compare_data,
215 GDestroyNotify key_destroy_func,
216 GDestroyNotify value_destroy_func)
220 g_return_val_if_fail (key_compare_func != NULL, NULL);
222 tree = g_slice_new (GTree);
224 tree->key_compare = key_compare_func;
225 tree->key_destroy_func = key_destroy_func;
226 tree->value_destroy_func = value_destroy_func;
227 tree->key_compare_data = key_compare_data;
238 * Returns the first in-order node of the tree, or %NULL
241 * Returns: (nullable) (transfer none): the first node in the tree
246 g_tree_node_first (GTree *tree)
250 g_return_val_if_fail (tree != NULL, NULL);
257 while (tmp->left_child)
267 * Returns the last in-order node of the tree, or %NULL
270 * Returns: (nullable) (transfer none): the last node in the tree
275 g_tree_node_last (GTree *tree)
279 g_return_val_if_fail (tree != NULL, NULL);
286 while (tmp->right_child)
293 * g_tree_node_previous
294 * @node: a #GTree node
296 * Returns the previous in-order node of the tree, or %NULL
297 * if the passed node was already the first one.
299 * Returns: (nullable) (transfer none): the previous node in the tree
304 g_tree_node_previous (GTreeNode *node)
308 g_return_val_if_fail (node != NULL, NULL);
312 if (node->left_child)
313 while (tmp->right_child)
321 * @node: a #GTree node
323 * Returns the next in-order node of the tree, or %NULL
324 * if the passed node was already the last one.
326 * Returns: (nullable) (transfer none): the next node in the tree
331 g_tree_node_next (GTreeNode *node)
335 g_return_val_if_fail (node != NULL, NULL);
339 if (node->right_child)
340 while (tmp->left_child)
350 * Removes all nodes from a #GTree and destroys their keys and values,
351 * then resets the #GTree’s root to %NULL.
356 g_tree_remove_all (GTree *tree)
361 g_return_if_fail (tree != NULL);
363 node = g_tree_node_first (tree);
367 next = g_tree_node_next (node);
369 if (tree->key_destroy_func)
370 tree->key_destroy_func (node->key);
371 if (tree->value_destroy_func)
372 tree->value_destroy_func (node->value);
373 g_slice_free (GTreeNode, node);
376 g_assert (tree->nnodes > 0);
384 g_assert (tree->nnodes == 0);
397 * Increments the reference count of @tree by one.
399 * It is safe to call this function from any thread.
401 * Returns: the passed in #GTree
406 g_tree_ref (GTree *tree)
408 g_return_val_if_fail (tree != NULL, NULL);
410 g_atomic_int_inc (&tree->ref_count);
419 * Decrements the reference count of @tree by one.
420 * If the reference count drops to 0, all keys and values will
421 * be destroyed (if destroy functions were specified) and all
422 * memory allocated by @tree will be released.
424 * It is safe to call this function from any thread.
429 g_tree_unref (GTree *tree)
431 g_return_if_fail (tree != NULL);
433 if (g_atomic_int_dec_and_test (&tree->ref_count))
435 g_tree_remove_all (tree);
436 g_slice_free (GTree, tree);
444 * Removes all keys and values from the #GTree and decreases its
445 * reference count by one. If keys and/or values are dynamically
446 * allocated, you should either free them first or create the #GTree
447 * using g_tree_new_full(). In the latter case the destroy functions
448 * you supplied will be called on all keys and values before destroying
452 g_tree_destroy (GTree *tree)
454 g_return_if_fail (tree != NULL);
456 g_tree_remove_all (tree);
461 g_tree_insert_replace_node_internal (GTree *tree,
465 gboolean null_ret_ok)
469 g_return_val_if_fail (tree != NULL, NULL);
471 node = g_tree_insert_internal (tree, key, value, replace, null_ret_ok);
474 g_tree_node_check (tree->root);
481 * g_tree_insert_node:
483 * @key: the key to insert
484 * @value: the value corresponding to the key
486 * Inserts a key/value pair into a #GTree.
488 * If the given key already exists in the #GTree its corresponding value
489 * is set to the new value. If you supplied a @value_destroy_func when
490 * creating the #GTree, the old value is freed using that function. If
491 * you supplied a @key_destroy_func when creating the #GTree, the passed
492 * key is freed using that function.
494 * The tree is automatically 'balanced' as new key/value pairs are added,
495 * so that the distance from the root to every leaf is as small as possible.
496 * The cost of maintaining a balanced tree while inserting new key/value
497 * result in a O(n log(n)) operation where most of the other operations
500 * Returns: (transfer none) (nullable): the inserted (or set) node or %NULL
501 * if insertion would overflow the tree node counter.
506 g_tree_insert_node (GTree *tree,
510 return g_tree_insert_replace_node_internal (tree, key, value, FALSE, TRUE);
516 * @key: the key to insert
517 * @value: the value corresponding to the key
519 * Inserts a key/value pair into a #GTree.
521 * Inserts a new key and value into a #GTree as g_tree_insert_node() does,
522 * only this function does not return the inserted or set node.
525 g_tree_insert (GTree *tree,
529 g_tree_insert_replace_node_internal (tree, key, value, FALSE, FALSE);
533 * g_tree_replace_node:
535 * @key: the key to insert
536 * @value: the value corresponding to the key
538 * Inserts a new key and value into a #GTree similar to g_tree_insert_node().
539 * The difference is that if the key already exists in the #GTree, it gets
540 * replaced by the new key. If you supplied a @value_destroy_func when
541 * creating the #GTree, the old value is freed using that function. If you
542 * supplied a @key_destroy_func when creating the #GTree, the old key is
543 * freed using that function.
545 * The tree is automatically 'balanced' as new key/value pairs are added,
546 * so that the distance from the root to every leaf is as small as possible.
548 * Returns: (transfer none) (nullable): the inserted (or set) node or %NULL
549 * if insertion would overflow the tree node counter.
554 g_tree_replace_node (GTree *tree,
558 return g_tree_insert_replace_node_internal (tree, key, value, TRUE, TRUE);
564 * @key: the key to insert
565 * @value: the value corresponding to the key
567 * Inserts a new key and value into a #GTree as g_tree_replace_node() does,
568 * only this function does not return the inserted or set node.
571 g_tree_replace (GTree *tree,
575 g_tree_insert_replace_node_internal (tree, key, value, TRUE, FALSE);
578 /* internal checked nnodes increment routine */
580 g_tree_nnodes_inc_checked (GTree *tree, gboolean overflow_fatal)
582 if (G_UNLIKELY (tree->nnodes == G_MAXUINT))
586 g_error ("Incrementing GTree nnodes counter would overflow");
597 /* internal insert routine */
599 g_tree_insert_internal (GTree *tree,
603 gboolean null_ret_ok)
605 GTreeNode *node, *retnode;
606 GTreeNode *path[MAX_GTREE_HEIGHT];
609 g_return_val_if_fail (tree != NULL, NULL);
613 tree->root = g_tree_node_new (key, value);
616 g_assert (tree->nnodes == 0);
629 int cmp = tree->key_compare (key, node->key, tree->key_compare_data);
633 if (tree->value_destroy_func)
634 tree->value_destroy_func (node->value);
640 if (tree->key_destroy_func)
641 tree->key_destroy_func (node->key);
647 /* free the passed key */
648 if (tree->key_destroy_func)
649 tree->key_destroy_func (key);
656 if (node->left_child)
665 if (!g_tree_nnodes_inc_checked (tree, !null_ret_ok))
670 child = g_tree_node_new (key, value);
671 child->left = node->left;
674 node->left_child = TRUE;
683 if (node->right_child)
692 if (!g_tree_nnodes_inc_checked (tree, !null_ret_ok))
697 child = g_tree_node_new (key, value);
698 child->right = node->right;
701 node->right_child = TRUE;
710 /* Restore balance. This is the goodness of a non-recursive
711 * implementation, when we are done with balancing we 'break'
712 * the loop and we are done.
716 GTreeNode *bparent = path[--idx];
717 gboolean left_node = (bparent && node == bparent->left);
718 g_assert (!bparent || bparent->left == node || bparent->right == node);
720 if (node->balance < -1 || node->balance > 1)
722 node = g_tree_node_balance (node);
726 bparent->left = node;
728 bparent->right = node;
731 if (node->balance == 0 || bparent == NULL)
735 bparent->balance -= 1;
737 bparent->balance += 1;
748 * @key: the key to remove
750 * Removes a key/value pair from a #GTree.
752 * If the #GTree was created using g_tree_new_full(), the key and value
753 * are freed using the supplied destroy functions, otherwise you have to
754 * make sure that any dynamically allocated values are freed yourself.
755 * If the key does not exist in the #GTree, the function does nothing.
757 * The cost of maintaining a balanced tree while removing a key/value
758 * result in a O(n log(n)) operation where most of the other operations
761 * Returns: %TRUE if the key was found (prior to 2.8, this function
765 g_tree_remove (GTree *tree,
770 g_return_val_if_fail (tree != NULL, FALSE);
772 removed = g_tree_remove_internal (tree, key, FALSE);
775 g_tree_node_check (tree->root);
784 * @key: the key to remove
786 * Removes a key and its associated value from a #GTree without calling
787 * the key and value destroy functions.
789 * If the key does not exist in the #GTree, the function does nothing.
791 * Returns: %TRUE if the key was found (prior to 2.8, this function
795 g_tree_steal (GTree *tree,
800 g_return_val_if_fail (tree != NULL, FALSE);
802 removed = g_tree_remove_internal (tree, key, TRUE);
805 g_tree_node_check (tree->root);
811 /* internal remove routine */
813 g_tree_remove_internal (GTree *tree,
817 GTreeNode *node, *parent, *balance;
818 GTreeNode *path[MAX_GTREE_HEIGHT];
822 g_return_val_if_fail (tree != NULL, FALSE);
833 int cmp = tree->key_compare (key, node->key, tree->key_compare_data);
839 if (!node->left_child)
847 if (!node->right_child)
855 /* The following code is almost equal to g_tree_remove_node,
856 * except that we do not have to call g_tree_node_parent.
858 balance = parent = path[--idx];
859 g_assert (!parent || parent->left == node || parent->right == node);
860 left_node = (parent && node == parent->left);
862 if (!node->left_child)
864 if (!node->right_child)
870 parent->left_child = FALSE;
871 parent->left = node->left;
872 parent->balance += 1;
876 parent->right_child = FALSE;
877 parent->right = node->right;
878 parent->balance -= 1;
881 else /* node has a right child */
883 GTreeNode *tmp = g_tree_node_next (node);
884 tmp->left = node->left;
887 tree->root = node->right;
890 parent->left = node->right;
891 parent->balance += 1;
895 parent->right = node->right;
896 parent->balance -= 1;
900 else /* node has a left child */
902 if (!node->right_child)
904 GTreeNode *tmp = g_tree_node_previous (node);
905 tmp->right = node->right;
908 tree->root = node->left;
911 parent->left = node->left;
912 parent->balance += 1;
916 parent->right = node->left;
917 parent->balance -= 1;
920 else /* node has a both children (pant, pant!) */
922 GTreeNode *prev = node->left;
923 GTreeNode *next = node->right;
924 GTreeNode *nextp = node;
925 int old_idx = idx + 1;
928 /* path[idx] == parent */
929 /* find the immediately next node (and its parent) */
930 while (next->left_child)
932 path[++idx] = nextp = next;
936 path[old_idx] = next;
939 /* remove 'next' from the tree */
942 if (next->right_child)
943 nextp->left = next->right;
945 nextp->left_child = FALSE;
948 next->right_child = TRUE;
949 next->right = node->right;
954 /* set the prev to point to the right place */
955 while (prev->right_child)
959 /* prepare 'next' to replace 'node' */
960 next->left_child = TRUE;
961 next->left = node->left;
962 next->balance = node->balance;
969 parent->right = next;
973 /* restore balance */
977 GTreeNode *bparent = path[--idx];
978 g_assert (!bparent || bparent->left == balance || bparent->right == balance);
979 left_node = (bparent && balance == bparent->left);
981 if(balance->balance < -1 || balance->balance > 1)
983 balance = g_tree_node_balance (balance);
985 tree->root = balance;
987 bparent->left = balance;
989 bparent->right = balance;
992 if (balance->balance != 0 || !bparent)
996 bparent->balance += 1;
998 bparent->balance -= 1;
1005 if (tree->key_destroy_func)
1006 tree->key_destroy_func (node->key);
1007 if (tree->value_destroy_func)
1008 tree->value_destroy_func (node->value);
1011 g_slice_free (GTreeNode, node);
1020 * @node: a #GTree node
1022 * Gets the key stored at a particular tree node.
1024 * Returns: (nullable) (transfer none): the key at the node.
1029 g_tree_node_key (GTreeNode *node)
1031 g_return_val_if_fail (node != NULL, NULL);
1037 * g_tree_node_value:
1038 * @node: a #GTree node
1040 * Gets the value stored at a particular tree node.
1042 * Returns: (nullable) (transfer none): the value at the node.
1047 g_tree_node_value (GTreeNode *node)
1049 g_return_val_if_fail (node != NULL, NULL);
1055 * g_tree_lookup_node:
1057 * @key: the key to look up
1059 * Gets the tree node corresponding to the given key. Since a #GTree is
1060 * automatically balanced as key/value pairs are added, key lookup
1061 * is O(log n) (where n is the number of key/value pairs in the tree).
1063 * Returns: (nullable) (transfer none): the tree node corresponding to
1064 * the key, or %NULL if the key was not found
1069 g_tree_lookup_node (GTree *tree,
1072 g_return_val_if_fail (tree != NULL, NULL);
1074 return g_tree_find_node (tree, key);
1080 * @key: the key to look up
1082 * Gets the value corresponding to the given key. Since a #GTree is
1083 * automatically balanced as key/value pairs are added, key lookup
1084 * is O(log n) (where n is the number of key/value pairs in the tree).
1086 * Returns: the value corresponding to the key, or %NULL
1087 * if the key was not found
1090 g_tree_lookup (GTree *tree,
1095 node = g_tree_lookup_node (tree, key);
1097 return node ? node->value : NULL;
1101 * g_tree_lookup_extended:
1103 * @lookup_key: the key to look up
1104 * @orig_key: (out) (optional) (nullable): returns the original key
1105 * @value: (out) (optional) (nullable): returns the value associated with the key
1107 * Looks up a key in the #GTree, returning the original key and the
1108 * associated value. This is useful if you need to free the memory
1109 * allocated for the original key, for example before calling
1112 * Returns: %TRUE if the key was found in the #GTree
1115 g_tree_lookup_extended (GTree *tree,
1116 gconstpointer lookup_key,
1122 g_return_val_if_fail (tree != NULL, FALSE);
1124 node = g_tree_find_node (tree, lookup_key);
1129 *orig_key = node->key;
1131 *value = node->value;
1141 * @func: the function to call for each node visited.
1142 * If this function returns %TRUE, the traversal is stopped.
1143 * @user_data: user data to pass to the function
1145 * Calls the given function for each of the key/value pairs in the #GTree.
1146 * The function is passed the key and value of each pair, and the given
1147 * @data parameter. The tree is traversed in sorted order.
1149 * The tree may not be modified while iterating over it (you can't
1150 * add/remove items). To remove all items matching a predicate, you need
1151 * to add each item to a list in your #GTraverseFunc as you walk over
1152 * the tree, then walk the list and remove each item.
1155 g_tree_foreach (GTree *tree,
1161 g_return_if_fail (tree != NULL);
1166 node = g_tree_node_first (tree);
1170 if ((*func) (node->key, node->value, user_data))
1173 node = g_tree_node_next (node);
1178 * g_tree_foreach_node:
1180 * @func: the function to call for each node visited.
1181 * If this function returns %TRUE, the traversal is stopped.
1182 * @user_data: user data to pass to the function
1184 * Calls the given function for each of the nodes in the #GTree.
1185 * The function is passed the pointer to the particular node, and the given
1186 * @data parameter. The tree traversal happens in-order.
1188 * The tree may not be modified while iterating over it (you can't
1189 * add/remove items). To remove all items matching a predicate, you need
1190 * to add each item to a list in your #GTraverseFunc as you walk over
1191 * the tree, then walk the list and remove each item.
1196 g_tree_foreach_node (GTree *tree,
1197 GTraverseNodeFunc func,
1202 g_return_if_fail (tree != NULL);
1207 node = g_tree_node_first (tree);
1211 if ((*func) (node, user_data))
1214 node = g_tree_node_next (node);
1221 * @traverse_func: the function to call for each node visited. If this
1222 * function returns %TRUE, the traversal is stopped.
1223 * @traverse_type: the order in which nodes are visited, one of %G_IN_ORDER,
1224 * %G_PRE_ORDER and %G_POST_ORDER
1225 * @user_data: user data to pass to the function
1227 * Calls the given function for each node in the #GTree.
1229 * Deprecated:2.2: The order of a balanced tree is somewhat arbitrary.
1230 * If you just want to visit all nodes in sorted order, use
1231 * g_tree_foreach() instead. If you really need to visit nodes in
1232 * a different order, consider using an [n-ary tree][glib-N-ary-Trees].
1236 * @key: a key of a #GTree node
1237 * @value: the value corresponding to the key
1238 * @data: user data passed to g_tree_traverse()
1240 * Specifies the type of function passed to g_tree_traverse(). It is
1241 * passed the key and value of each node, together with the @user_data
1242 * parameter passed to g_tree_traverse(). If the function returns
1243 * %TRUE, the traversal is stopped.
1245 * Returns: %TRUE to stop the traversal
1248 g_tree_traverse (GTree *tree,
1249 GTraverseFunc traverse_func,
1250 GTraverseType traverse_type,
1253 g_return_if_fail (tree != NULL);
1258 switch (traverse_type)
1261 g_tree_node_pre_order (tree->root, traverse_func, user_data);
1265 g_tree_node_in_order (tree->root, traverse_func, user_data);
1269 g_tree_node_post_order (tree->root, traverse_func, user_data);
1273 g_warning ("g_tree_traverse(): traverse type G_LEVEL_ORDER isn't implemented.");
1279 * g_tree_search_node:
1281 * @search_func: a function used to search the #GTree
1282 * @user_data: the data passed as the second argument to @search_func
1284 * Searches a #GTree using @search_func.
1286 * The @search_func is called with a pointer to the key of a key/value
1287 * pair in the tree, and the passed in @user_data. If @search_func returns
1288 * 0 for a key/value pair, then the corresponding node is returned as
1289 * the result of g_tree_search(). If @search_func returns -1, searching
1290 * will proceed among the key/value pairs that have a smaller key; if
1291 * @search_func returns 1, searching will proceed among the key/value
1292 * pairs that have a larger key.
1294 * Returns: (nullable) (transfer none): the node corresponding to the
1295 * found key, or %NULL if the key was not found
1300 g_tree_search_node (GTree *tree,
1301 GCompareFunc search_func,
1302 gconstpointer user_data)
1304 g_return_val_if_fail (tree != NULL, NULL);
1309 return g_tree_node_search (tree->root, search_func, user_data);
1315 * @search_func: a function used to search the #GTree
1316 * @user_data: the data passed as the second argument to @search_func
1318 * Searches a #GTree using @search_func.
1320 * The @search_func is called with a pointer to the key of a key/value
1321 * pair in the tree, and the passed in @user_data. If @search_func returns
1322 * 0 for a key/value pair, then the corresponding value is returned as
1323 * the result of g_tree_search(). If @search_func returns -1, searching
1324 * will proceed among the key/value pairs that have a smaller key; if
1325 * @search_func returns 1, searching will proceed among the key/value
1326 * pairs that have a larger key.
1328 * Returns: the value corresponding to the found key, or %NULL
1329 * if the key was not found
1332 g_tree_search (GTree *tree,
1333 GCompareFunc search_func,
1334 gconstpointer user_data)
1338 node = g_tree_search_node (tree, search_func, user_data);
1340 return node ? node->value : NULL;
1344 * g_tree_lower_bound:
1346 * @key: the key to calculate the lower bound for
1348 * Gets the lower bound node corresponding to the given key,
1349 * or %NULL if the tree is empty or all the nodes in the tree
1350 * have keys that are strictly lower than the searched key.
1352 * The lower bound is the first node that has its key greater
1353 * than or equal to the searched key.
1355 * Returns: (nullable) (transfer none): the tree node corresponding to
1356 * the lower bound, or %NULL if the tree is empty or has only
1357 * keys strictly lower than the searched key.
1362 g_tree_lower_bound (GTree *tree,
1365 GTreeNode *node, *result;
1368 g_return_val_if_fail (tree != NULL, NULL);
1377 cmp = tree->key_compare (key, node->key, tree->key_compare_data);
1382 if (!node->left_child)
1389 if (!node->right_child)
1398 * g_tree_upper_bound:
1400 * @key: the key to calculate the upper bound for
1402 * Gets the upper bound node corresponding to the given key,
1403 * or %NULL if the tree is empty or all the nodes in the tree
1404 * have keys that are lower than or equal to the searched key.
1406 * The upper bound is the first node that has its key strictly greater
1407 * than the searched key.
1409 * Returns: (nullable) (transfer none): the tree node corresponding to the
1410 * upper bound, or %NULL if the tree is empty or has only keys
1411 * lower than or equal to the searched key.
1416 g_tree_upper_bound (GTree *tree,
1419 GTreeNode *node, *result;
1422 g_return_val_if_fail (tree != NULL, NULL);
1431 cmp = tree->key_compare (key, node->key, tree->key_compare_data);
1436 if (!node->left_child)
1443 if (!node->right_child)
1455 * Gets the height of a #GTree.
1457 * If the #GTree contains no nodes, the height is 0.
1458 * If the #GTree contains only one root node the height is 1.
1459 * If the root node has children the height is 2, etc.
1461 * Returns: the height of @tree
1464 g_tree_height (GTree *tree)
1469 g_return_val_if_fail (tree != NULL, 0);
1479 height += 1 + MAX(node->balance, 0);
1481 if (!node->left_child)
1492 * Gets the number of nodes in a #GTree.
1494 * Returns: the number of nodes in @tree
1496 * The node counter value type is really a #guint,
1497 * but it is returned as a #gint due to backward
1498 * compatibility issues (can be cast back to #guint to
1499 * support its full range of values).
1502 g_tree_nnodes (GTree *tree)
1504 g_return_val_if_fail (tree != NULL, 0);
1506 return tree->nnodes;
1510 g_tree_node_balance (GTreeNode *node)
1512 if (node->balance < -1)
1514 if (node->left->balance > 0)
1515 node->left = g_tree_node_rotate_left (node->left);
1516 node = g_tree_node_rotate_right (node);
1518 else if (node->balance > 1)
1520 if (node->right->balance < 0)
1521 node->right = g_tree_node_rotate_right (node->right);
1522 node = g_tree_node_rotate_left (node);
1529 g_tree_find_node (GTree *tree,
1541 cmp = tree->key_compare (key, node->key, tree->key_compare_data);
1546 if (!node->left_child)
1553 if (!node->right_child)
1562 g_tree_node_pre_order (GTreeNode *node,
1563 GTraverseFunc traverse_func,
1566 if ((*traverse_func) (node->key, node->value, data))
1569 if (node->left_child)
1571 if (g_tree_node_pre_order (node->left, traverse_func, data))
1575 if (node->right_child)
1577 if (g_tree_node_pre_order (node->right, traverse_func, data))
1585 g_tree_node_in_order (GTreeNode *node,
1586 GTraverseFunc traverse_func,
1589 if (node->left_child)
1591 if (g_tree_node_in_order (node->left, traverse_func, data))
1595 if ((*traverse_func) (node->key, node->value, data))
1598 if (node->right_child)
1600 if (g_tree_node_in_order (node->right, traverse_func, data))
1608 g_tree_node_post_order (GTreeNode *node,
1609 GTraverseFunc traverse_func,
1612 if (node->left_child)
1614 if (g_tree_node_post_order (node->left, traverse_func, data))
1618 if (node->right_child)
1620 if (g_tree_node_post_order (node->right, traverse_func, data))
1624 if ((*traverse_func) (node->key, node->value, data))
1631 g_tree_node_search (GTreeNode *node,
1632 GCompareFunc search_func,
1642 dir = (* search_func) (node->key, data);
1647 if (!node->left_child)
1654 if (!node->right_child)
1663 g_tree_node_rotate_left (GTreeNode *node)
1669 right = node->right;
1671 if (right->left_child)
1672 node->right = right->left;
1675 node->right_child = FALSE;
1676 right->left_child = TRUE;
1680 a_bal = node->balance;
1681 b_bal = right->balance;
1686 right->balance = b_bal - 1;
1688 right->balance = a_bal + b_bal - 2;
1689 node->balance = a_bal - 1;
1694 right->balance = a_bal - 2;
1696 right->balance = b_bal - 1;
1697 node->balance = a_bal - b_bal - 1;
1704 g_tree_node_rotate_right (GTreeNode *node)
1712 if (left->right_child)
1713 node->left = left->right;
1716 node->left_child = FALSE;
1717 left->right_child = TRUE;
1721 a_bal = node->balance;
1722 b_bal = left->balance;
1727 left->balance = b_bal + 1;
1729 left->balance = a_bal + 2;
1730 node->balance = a_bal - b_bal + 1;
1735 left->balance = b_bal + 1;
1737 left->balance = a_bal + b_bal + 2;
1738 node->balance = a_bal + 1;
1746 g_tree_node_height (GTreeNode *node)
1756 if (node->left_child)
1757 left_height = g_tree_node_height (node->left);
1759 if (node->right_child)
1760 right_height = g_tree_node_height (node->right);
1762 return MAX (left_height, right_height) + 1;
1769 g_tree_node_check (GTreeNode *node)
1778 if (node->left_child)
1780 tmp = g_tree_node_previous (node);
1781 g_assert (tmp->right == node);
1784 if (node->right_child)
1786 tmp = g_tree_node_next (node);
1787 g_assert (tmp->left == node);
1793 if (node->left_child)
1794 left_height = g_tree_node_height (node->left);
1795 if (node->right_child)
1796 right_height = g_tree_node_height (node->right);
1798 balance = right_height - left_height;
1799 g_assert (balance == node->balance);
1801 if (node->left_child)
1802 g_tree_node_check (node->left);
1803 if (node->right_child)
1804 g_tree_node_check (node->right);
1809 g_tree_node_dump (GTreeNode *node,
1812 g_print ("%*s%c\n", indent, "", *(char *)node->key);
1814 if (node->left_child)
1816 g_print ("%*sLEFT\n", indent, "");
1817 g_tree_node_dump (node->left, indent + 2);
1819 else if (node->left)
1820 g_print ("%*s<%c\n", indent + 2, "", *(char *)node->left->key);
1822 if (node->right_child)
1824 g_print ("%*sRIGHT\n", indent, "");
1825 g_tree_node_dump (node->right, indent + 2);
1827 else if (node->right)
1828 g_print ("%*s>%c\n", indent + 2, "", *(char *)node->right->key);
1832 g_tree_dump (GTree *tree)
1835 g_tree_node_dump (tree->root, 0);