1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * GNode: N-way tree implementation.
5 * Copyright (C) 1998 Tim Janik
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library 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 GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 #define KEEP_NODES (1024)
28 /* --- variables --- */
29 static GMemChunk *g_tree_node_chunk = NULL;
30 static GNode *free_nodes = NULL;
31 static guint n_free_nodes = 0;
34 /* --- functions --- */
36 g_node_new (gpointer data)
40 if (!g_tree_node_chunk)
41 g_tree_node_chunk = g_mem_chunk_create (GNode, 1024, G_ALLOC_AND_FREE);
46 free_nodes = free_nodes->next;
50 node = g_chunk_new (GNode, g_tree_node_chunk);
56 node->children = NULL;
62 g_node_free (GNode *parent)
66 node = parent->children;
70 register GNode *free_node;
73 node = free_node->next;
74 g_node_free (free_node);
77 if (n_free_nodes < KEEP_NODES)
79 parent->next = free_nodes;
84 g_chunk_free (parent, g_tree_node_chunk);
88 g_node_destroy (GNode *root)
90 g_return_if_fail (root != NULL);
92 if (!G_NODE_IS_ROOT (root))
99 g_node_unlink (GNode *node)
101 g_return_if_fail (node != NULL);
104 node->prev->next = node->next;
105 else if (node->parent)
106 node->parent->children = node->next;
110 node->next->prev = node->prev;
117 g_node_insert (GNode *parent,
121 g_return_val_if_fail (parent != NULL, node);
122 g_return_val_if_fail (node != NULL, node);
123 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
126 return g_node_insert_before (parent,
127 g_node_nth_child (parent, position),
129 else if (position == 0)
130 return g_node_prepend (parent, node);
131 else /* if (position < 0) */
132 return g_node_append (parent, node);
136 g_node_insert_before (GNode *parent,
140 g_return_val_if_fail (parent != NULL, node);
141 g_return_val_if_fail (node != NULL, node);
142 g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
144 g_return_val_if_fail (sibling->parent == parent, node);
146 node->parent = parent;
152 node->prev = sibling->prev;
153 node->prev->next = node;
154 node->next = sibling;
155 sibling->prev = node;
159 node->parent->children = node;
160 node->next = sibling;
161 sibling->prev = node;
166 if (parent->children)
168 sibling = parent->children;
169 while (sibling->next)
170 sibling = sibling->next;
171 node->prev = sibling;
172 sibling->next = node;
175 node->parent->children = node;
182 g_node_prepend (GNode *parent,
185 g_return_val_if_fail (parent != NULL, node);
187 return g_node_insert_before (parent, parent->children, node);
191 g_node_get_root (GNode *node)
193 g_return_val_if_fail (node != NULL, NULL);
202 g_node_is_ancestor (GNode *node,
205 g_return_val_if_fail (node != NULL, FALSE);
206 g_return_val_if_fail (descendant != NULL, FALSE);
210 if (descendant->parent == node)
213 descendant = descendant->parent;
219 /* returns 1 for root, 2 for first level children,
220 * 3 for children's children...
223 g_node_depth (GNode *node)
225 register guint depth = 0;
237 g_node_reverse_children (GNode *node)
242 g_return_if_fail (node != NULL);
244 child = node->children;
250 last->next = last->prev;
253 node->children = last;
257 g_node_max_height (GNode *root)
259 register GNode *child;
260 register guint max_height = 0;
265 child = root->children;
268 register guint tmp_height;
270 tmp_height = g_node_max_height (child);
271 if (tmp_height > max_height)
272 max_height = tmp_height;
276 return max_height + 1;
280 g_node_traverse_pre_order (GNode *node,
281 GTraverseFlags flags,
282 GNodeTraverseFunc func,
289 if ((flags & G_TRAVERSE_NON_LEAFS) &&
293 child = node->children;
296 register GNode *current;
299 child = current->next;
300 if (g_node_traverse_pre_order (current, flags, func, data))
304 else if ((flags & G_TRAVERSE_LEAFS) &&
312 g_node_depth_traverse_pre_order (GNode *node,
313 GTraverseFlags flags,
315 GNodeTraverseFunc func,
322 if ((flags & G_TRAVERSE_NON_LEAFS) &&
330 child = node->children;
333 register GNode *current;
336 child = current->next;
337 if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
341 else if ((flags & G_TRAVERSE_LEAFS) &&
349 g_node_traverse_post_order (GNode *node,
350 GTraverseFlags flags,
351 GNodeTraverseFunc func,
358 child = node->children;
361 register GNode *current;
364 child = current->next;
365 if (g_node_traverse_post_order (current, flags, func, data))
369 if ((flags & G_TRAVERSE_NON_LEAFS) &&
374 else if ((flags & G_TRAVERSE_LEAFS) &&
382 g_node_depth_traverse_post_order (GNode *node,
383 GTraverseFlags flags,
385 GNodeTraverseFunc func,
395 child = node->children;
398 register GNode *current;
401 child = current->next;
402 if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
407 if ((flags & G_TRAVERSE_NON_LEAFS) &&
412 else if ((flags & G_TRAVERSE_LEAFS) &&
420 g_node_traverse_in_order (GNode *node,
421 GTraverseFlags flags,
422 GNodeTraverseFunc func,
428 register GNode *current;
430 child = node->children;
432 child = current->next;
434 if (g_node_traverse_in_order (current, flags, func, data))
437 if ((flags & G_TRAVERSE_NON_LEAFS) &&
444 child = current->next;
445 if (g_node_traverse_in_order (current, flags, func, data))
449 else if ((flags & G_TRAVERSE_LEAFS) &&
457 g_node_depth_traverse_in_order (GNode *node,
458 GTraverseFlags flags,
460 GNodeTraverseFunc func,
469 register GNode *current;
471 child = node->children;
473 child = current->next;
475 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
478 if ((flags & G_TRAVERSE_NON_LEAFS) &&
485 child = current->next;
486 if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
490 else if ((flags & G_TRAVERSE_NON_LEAFS) &&
494 else if ((flags & G_TRAVERSE_LEAFS) &&
502 g_node_traverse_children (GNode *node,
503 GTraverseFlags flags,
504 GNodeTraverseFunc func,
509 child = node->children;
513 register GNode *current;
516 child = current->next;
518 if (current->children)
520 if ((flags & G_TRAVERSE_NON_LEAFS) &&
521 func (current, data))
524 else if ((flags & G_TRAVERSE_LEAFS) &&
525 func (current, data))
529 child = node->children;
533 register GNode *current;
536 child = current->next;
538 if (current->children &&
539 g_node_traverse_children (current, flags, func, data))
547 g_node_depth_traverse_children (GNode *node,
548 GTraverseFlags flags,
550 GNodeTraverseFunc func,
555 child = node->children;
559 register GNode *current;
562 child = current->next;
564 if (current->children)
566 if ((flags & G_TRAVERSE_NON_LEAFS) &&
567 func (current, data))
570 else if ((flags & G_TRAVERSE_LEAFS) &&
571 func (current, data))
579 child = node->children;
583 register GNode *current;
586 child = current->next;
588 if (current->children &&
589 g_node_depth_traverse_children (current, flags, depth, func, data))
597 g_node_traverse (GNode *root,
599 GTraverseFlags flags,
601 GNodeTraverseFunc func,
604 g_return_if_fail (root != NULL);
605 g_return_if_fail (func != NULL);
606 g_return_if_fail (order <= G_LEVEL_ORDER);
607 g_return_if_fail (flags <= G_TRAVERSE_MASK);
608 g_return_if_fail (depth == -1 || depth > 0);
614 g_node_traverse_pre_order (root, flags, func, data);
616 g_node_depth_traverse_pre_order (root, flags, depth, func, data);
620 g_node_traverse_post_order (root, flags, func, data);
622 g_node_depth_traverse_post_order (root, flags, depth, func, data);
626 g_node_traverse_in_order (root, flags, func, data);
628 g_node_depth_traverse_in_order (root, flags, depth, func, data);
633 if (!((flags & G_TRAVERSE_NON_LEAFS) &&
637 g_node_traverse_children (root, flags, func, data);
642 g_node_depth_traverse_children (root, flags, depth, func, data);
646 else if (flags & G_TRAVERSE_LEAFS)
653 g_node_find_func (GNode *node,
656 register gpointer *d = data;
658 if (*d != node->data)
667 g_node_find (GNode *root,
669 GTraverseFlags flags,
674 g_return_val_if_fail (root != NULL, NULL);
675 g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
676 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
681 g_node_traverse (root, order, flags, -1, g_node_find_func, d);
687 g_node_count_func (GNode *node,
688 GTraverseFlags flags,
695 if (flags & G_TRAVERSE_NON_LEAFS)
698 child = node->children;
701 g_node_count_func (child, flags, n);
705 else if (flags & G_TRAVERSE_LEAFS)
710 g_node_n_nodes (GNode *root,
711 GTraverseFlags flags)
715 g_return_val_if_fail (root != NULL, 0);
716 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
718 g_node_count_func (root, flags, &n);
724 g_node_last_child (GNode *node)
726 g_return_val_if_fail (node != NULL, NULL);
728 node = node->children;
737 g_node_nth_child (GNode *node,
740 g_return_val_if_fail (node != NULL, NULL);
742 node = node->children;
744 while ((n-- > 0) && node)
751 g_node_n_children (GNode *node)
755 g_return_val_if_fail (node != NULL, 0);
757 node = node->children;
768 g_node_find_child (GNode *node,
769 GTraverseFlags flags,
772 g_return_val_if_fail (node != NULL, NULL);
773 g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
775 node = node->children;
778 if (node->data == data)
780 if (G_NODE_IS_LEAF (node))
782 if (flags & G_TRAVERSE_LEAFS)
787 if (flags & G_TRAVERSE_NON_LEAFS)
798 g_node_child_position (GNode *node,
801 register guint n = 0;
803 g_return_val_if_fail (node != NULL, -1);
804 g_return_val_if_fail (child != NULL, -1);
805 g_return_val_if_fail (child->parent == node, -1);
807 node = node->children;
820 g_node_child_index (GNode *node,
823 register guint n = 0;
825 g_return_val_if_fail (node != NULL, -1);
827 node = node->children;
830 if (node->data == data)
840 g_node_first_sibling (GNode *node)
842 g_return_val_if_fail (node != NULL, NULL);
851 g_node_last_sibling (GNode *node)
853 g_return_val_if_fail (node != NULL, NULL);
862 g_node_children_foreach (GNode *node,
863 GTraverseFlags flags,
864 GNodeForeachFunc func,
867 g_return_if_fail (node != NULL);
868 g_return_if_fail (flags <= G_TRAVERSE_MASK);
869 g_return_if_fail (func != NULL);
871 node = node->children;
874 register GNode *current;
877 node = current->next;
878 if (G_NODE_IS_LEAF (node))
880 if (flags & G_TRAVERSE_LEAFS)
881 func (current, data);
885 if (flags & G_TRAVERSE_NON_LEAFS)
886 func (current, data);