1 /* indent -blC -bli0 -npcs -ncs -i4 -bad -bap avl.c */
3 Copyright (c) 2008, The AROS Development Team. All rights reserved.
5 #Description: @AROS.Exec.AVL@
7 <chapter title="Exec AVL Trees">
9 <p>FIXME explain it</p>
15 #include <proto/exec.h>
18 /* don't think this works inside exec.library */
24 /* internal functions */
25 /* Re-Links the parent of subroot, properly handling the root-node.
26 The old parent is supplied in parent */
28 link_parent(struct AVLNode
**root
, const struct AVLNode
*scan
,
29 struct AVLNode
*subroot
, struct AVLNode
*parent
)
36 subroot
->avl_parent
= NULL
;
41 dir
= parent
->avl_link
[1] == scan
;
42 parent
->avl_link
[dir
] = subroot
;
43 subroot
->avl_parent
= parent
;
49 /* Perform a single rotation about next in the given direction.
50 Note that this will be inlined with hard-coded dirs */
51 static inline struct AVLNode
*
52 rotate_single(struct AVLNode
*scan
, struct AVLNode
*next
, const int dir
)
54 struct AVLNode
*subroot
= next
;
55 const int other
= dir
== 0;
57 D(printf("single %s about %p\n", dir
== 0 ? "left" : "right", subroot
));
59 scan
->avl_link
[other
] = next
->avl_link
[dir
];
60 if (next
->avl_link
[dir
] != NULL
)
61 next
->avl_link
[dir
]->avl_parent
= scan
;
62 next
->avl_link
[dir
] = scan
;
63 scan
->avl_parent
= next
;
68 /* Peform a double rotation about scan and then next in a given direction
69 Note that this will be in-lined with hard-coded dirs */
70 static inline struct AVLNode
*
71 rotate_double(struct AVLNode
*scan
, struct AVLNode
*next
, const int dir
)
73 struct AVLNode
*subroot
= next
->avl_link
[dir
];
74 const int other
= dir
== 0;
76 D(printf("double %s about %p\n", dir
== 0 ? "left" : "right", subroot
));
78 next
->avl_link
[dir
] = subroot
->avl_link
[other
];
79 if (subroot
->avl_link
[other
] != NULL
)
80 subroot
->avl_link
[other
]->avl_parent
= next
;
81 subroot
->avl_link
[other
] = next
;
82 scan
->avl_link
[other
] = subroot
->avl_link
[dir
];
83 if (subroot
->avl_link
[dir
] != NULL
)
84 subroot
->avl_link
[dir
]->avl_parent
= scan
;
85 subroot
->avl_link
[dir
] = scan
;
87 next
->avl_parent
= subroot
;
88 scan
->avl_parent
= subroot
;
93 /*****************************************************************************
97 AROS_LH3I(struct AVLNode
*, AVL_AddNode
,
100 AROS_LHA(struct AVLNode
**, root
, A0
),
101 AROS_LHA(struct AVLNode
*, node
, A1
),
102 AROS_LHA(AVLNODECOMP
, func
, A2
),
104 struct ExecBase
*, SysBase
, 142, Exec
)
106 Add a new node to an AVL tree.
109 Root - The root node of the tree to which the new node will be added.
110 Initially and if the tree is empty, this will be NULL.
112 Node - The new node to add. Any key information must alread be
115 Func - A key comparison function. It will be passed 2 nodes,
116 node1 and node2 to compare and must return <0, 0 or >0 to
117 reflect node1 < node2, node1 == node, or node1 > node2
121 NULL if the node was added to the tree, or a pointer to a node with the
122 same key which already exists in the tree.
125 AVL trees are balanced binary search trees. This implementation is
126 based on embedding the struct AVLNode within your own data object
127 and providing custom comparison functions wherever they are needed.
129 Two comparison functions are needed for different cases. It is entirely
130 up to the application as to how it interprets the nodes and compares
133 AVLNODECOMP is used to compare the keys of two nodes.
135 typedef LONG *AVLNODECOMP(const struct AVLNode *avlnode1,
136 const struct AVLNode *avlnode2);
139 AVLKEYCOMP is used to compare a key to a node.
141 typedef LONG *AVLKEYCOMP(const struct AVLNode *avlnode,
145 These functions must return the same sense for the same key values.
147 <0 if key of avlnode1 < key of avlnode2
148 if key of avlnode < key
149 0 if key of avlnode1 == key of avlnode2
150 if key of avlnode == key
151 >0 if key of avlnode1 > key of avlnode2
152 if key of avlnode < key
154 Since this function returns the existing node if the keys match,
155 this function can be used to efficiently add items to the tree or
156 update existing items without requiring additional lookups.
159 This is a fragment which counts the occurances of every word in a file.
160 Also note that this example embeds the struct AVLNode data at
161 the start of the structure, so simple casts suffice for translating
162 AVLNode to ExampleNode addresses.
170 static LONG ExampleNodeComp(const struct AVLNode *a1, const struct AVLNode *a2)
172 const struct ExampleNode *e1 = (const struct ExampleNode *)a1;
173 const struct ExampleNode *e2 = (const struct ExampleNode *)e2;
175 return strcmp(a1->key, a2->key);
178 static LONG ExampleKeyComp(const struct AVLNode *a1, AVLKey key)
180 const struct ExampleNode *e1 = (const struct ExampleNode *)a1;
183 return strcmp(a1->key, skey);
186 void CountWords(wordfile)
188 struct ExampleNode *node;
189 struct AVLNode *root = NULL, *check;
191 node = AllocMem(sizeof(struct ExampleNode), 0);
194 while (node->key = read_word(wordfile)) {
195 check = AVL_AddNode(&root, &node->avl, ExampleNodecomp);
198 struct ExampleNode *work = (struct ExampleNode *)check;
203 node = AllocMem(sizeof(struct ExampleNode), 0);
207 FreeMem(node, sizeof(struct ExampleNode));
213 AVL_FindNode(), AVL_FindNextNodeByKey(), AVL_FindPrevNodeByKey(),
214 AVL_RemNodeByAddress(), AVL_RemNodeByKey()
217 ******************************************************************************/
222 struct AVLNode
*next
= *root
;
223 struct AVLNode
*scan
;
224 struct AVLNode
*child
;
226 /* Simple case - empty tree */
230 node
->avl_link
[0] = node
->avl_link
[1] = node
->avl_parent
= NULL
;
231 node
->avl_balance
= 0;
235 /* find insertion point */
241 cmp
= func(scan
, node
);
243 return (struct AVLNode
*)scan
;
246 next
= scan
->avl_link
[dir
];
248 while (next
!= NULL
);
251 node
->avl_parent
= scan
;
252 scan
->avl_link
[dir
] = node
;
253 node
->avl_link
[0] = node
->avl_link
[1] = NULL
;
254 node
->avl_balance
= 0;
256 /* update balance factors */
259 LONG bal
= (dir
* 2 - 1) + scan
->avl_balance
;
260 struct AVLNode
*parent
;
261 struct AVLNode
*subroot
;
266 scan
->avl_balance
= bal
;
270 parent
= scan
->avl_parent
;
271 next
= scan
->avl_link
[1];
273 switch (next
->avl_balance
)
276 subroot
= rotate_double(scan
, next
, LEFT
);
278 if (subroot
->avl_balance
== 1)
280 scan
->avl_balance
= -1;
281 next
->avl_balance
= 0;
283 else if (subroot
->avl_balance
== -1)
285 scan
->avl_balance
= 0;
286 next
->avl_balance
= 1;
290 scan
->avl_balance
= next
->avl_balance
= 0;
293 subroot
->avl_balance
= 0;
296 subroot
= rotate_single(scan
, next
, LEFT
);
298 scan
->avl_balance
= next
->avl_balance
= 0;
302 link_parent(root
, scan
, subroot
, parent
);
306 parent
= scan
->avl_parent
;
307 next
= scan
->avl_link
[0];
309 switch (next
->avl_balance
)
312 subroot
= rotate_double(scan
, next
, RIGHT
);
314 if (subroot
->avl_balance
== -1)
316 scan
->avl_balance
= 1;
317 next
->avl_balance
= 0;
319 else if (subroot
->avl_balance
== 1)
321 scan
->avl_balance
= 0;
322 next
->avl_balance
= -1;
326 scan
->avl_balance
= next
->avl_balance
= 0;
329 subroot
->avl_balance
= 0;
332 subroot
= rotate_single(scan
, next
, RIGHT
);
334 scan
->avl_balance
= next
->avl_balance
= 0;
338 link_parent(root
, scan
, subroot
, parent
);
342 scan
->avl_balance
= bal
;
345 scan
= scan
->avl_parent
;
349 dir
= scan
->avl_link
[1] == child
;
359 /*****************************************************************************
363 AROS_LH2I(struct AVLNode
*, AVL_RemNodeByAddress
,
366 AROS_LHA(struct AVLNode
**, Root
, A0
),
367 AROS_LHA(struct AVLNode
*, Node
, A1
),
369 struct ExecBase
*, SysBase
, 143, Exec
)
371 Remove a given node from the tree.
374 Root - A pointer to a pointer to the root node of the tree.
376 Node - A struct AVLNode to remove. The node must be present
383 Removing a node may require multiple rebalancing steps
384 in the tree. Each step however runs in constant time
385 and no more than 1.44log(n) steps will be required.
388 See AVL_NextNodeByAddress(), AVL_PrevNodeByAddress()
393 AVL_AddNode(), AVL_FindNode(), AVL_NextNodeByAddress(),
394 AVL_PrevNodeByAddress()
397 ******************************************************************************/
401 struct AVLNode
*scan
;
402 struct AVLNode
*node
= (struct AVLNode
*)Node
;
403 struct AVLNode
**root
= (struct AVLNode
**)Root
;
406 if (node
->avl_link
[0] == NULL
)
408 if (node
->avl_link
[1] == NULL
)
410 if (node
->avl_parent
== NULL
)
412 /* removed last node */
419 scan
= node
->avl_parent
;
420 dir
= scan
->avl_link
[1] == node
;
421 scan
->avl_link
[dir
] = NULL
;
422 D(printf("removed leaf dir = %d\n", dir
));
427 if (node
->avl_parent
== NULL
)
429 /* removed root left-leaf node */
430 *root
= node
->avl_link
[1];
431 node
->avl_link
[1]->avl_parent
= NULL
;
436 /* removed a left-leaf */
437 scan
= node
->avl_parent
;
438 dir
= scan
->avl_link
[1] == node
;
439 scan
->avl_link
[dir
] = node
->avl_link
[1];
440 node
->avl_link
[1]->avl_parent
= scan
;
441 D(printf("removed left leaf dir =%d\n", dir
));
447 if (node
->avl_link
[1] == NULL
)
449 if (node
->avl_parent
== NULL
)
451 /* removed root right-leaf node */
452 *root
= node
->avl_link
[0];
453 node
->avl_link
[0]->avl_parent
= NULL
;
458 /* removed a right-leaf */
459 scan
= node
->avl_parent
;
460 dir
= scan
->avl_link
[1] == node
;
461 scan
->avl_link
[dir
] = node
->avl_link
[0];
462 node
->avl_link
[0]->avl_parent
= scan
;
463 D(printf("removed right leaf dir=%d\n", dir
));
468 /* removing a non-leaf node - swap it with a leaf node and 'remove' that instead */
469 struct AVLNode
*toremove
= (struct AVLNode
*)AVL_FindPrevNodeByAddress(Node
); // do we do prev/next based on balance factor? */
471 D(printf("removing non-leaf key ... %p\n", toremove
));
473 /* remove the leaf node */
474 scan
= toremove
->avl_parent
;
478 /* special case - immediate child of what we're removing */
479 toremove
->avl_link
[1] = node
->avl_link
[1];
480 if (node
->avl_link
[1] != NULL
)
481 node
->avl_link
[1]->avl_parent
= toremove
;
484 D(printf(" removed immediate child\n"));
488 dir
= toremove
->avl_parent
->avl_link
[1] == toremove
;
489 toremove
->avl_parent
->avl_link
[dir
] = toremove
->avl_link
[0];
490 if (toremove
->avl_link
[0] != NULL
)
491 toremove
->avl_link
[0]->avl_parent
= toremove
->avl_parent
;
493 /* swap it with the removed node */
494 toremove
->avl_link
[0] = node
->avl_link
[0];
495 if (node
->avl_link
[0] != NULL
)
496 node
->avl_link
[0]->avl_parent
= toremove
;
497 toremove
->avl_link
[1] = node
->avl_link
[1];
498 if (node
->avl_link
[1] != NULL
)
499 node
->avl_link
[1]->avl_parent
= toremove
;
500 D(printf(" removed distant child\n"));
502 toremove
->avl_balance
= node
->avl_balance
;
503 toremove
->avl_parent
= node
->avl_parent
;
504 if (node
->avl_parent
== NULL
)
507 node
->avl_parent
->avl_link
[node
->avl_parent
->avl_link
[1] ==
510 D(printf("removed key, tree is now:\n"));
511 D(dumptree(*root
, 0));
515 /* rebalance from 'scan' up */
518 int bal
= scan
->avl_balance
- (dir
* 2 - 1);
519 struct AVLNode
*next
;
520 struct AVLNode
*parent
;
521 struct AVLNode
*subroot
;
526 scan
->avl_balance
= bal
;
528 parent
= scan
->avl_parent
;
532 dir
= parent
->avl_link
[1] == scan
;
538 scan
->avl_balance
= bal
;
542 parent
= scan
->avl_parent
;
543 next
= scan
->avl_link
[1];
545 switch (next
->avl_balance
)
548 subroot
= rotate_single(scan
, next
, LEFT
);
549 scan
->avl_balance
= 1;
550 next
->avl_balance
= -1;
552 link_parent(root
, scan
, subroot
, parent
);
555 subroot
= rotate_single(scan
, next
, LEFT
);
556 scan
->avl_balance
= 0;
557 next
->avl_balance
= 0;
561 subroot
= rotate_double(scan
, next
, LEFT
);
563 if (subroot
->avl_balance
== 1)
565 scan
->avl_balance
= -1;
566 next
->avl_balance
= 0;
568 else if (subroot
->avl_balance
== -1)
570 scan
->avl_balance
= 0;
571 next
->avl_balance
= 1;
575 scan
->avl_balance
= 0;
576 next
->avl_balance
= 0;
579 subroot
->avl_balance
= 0;
584 dir
= link_parent(root
, scan
, subroot
, parent
);
592 parent
= scan
->avl_parent
;
593 next
= scan
->avl_link
[0];
595 switch (next
->avl_balance
)
598 subroot
= rotate_single(scan
, next
, RIGHT
);
599 scan
->avl_balance
= -1;
600 next
->avl_balance
= 1;
602 link_parent(root
, scan
, subroot
, parent
);
605 subroot
= rotate_single(scan
, next
, RIGHT
);
606 scan
->avl_balance
= next
->avl_balance
= 0;
610 subroot
= rotate_double(scan
, next
, RIGHT
);
612 if (subroot
->avl_balance
== -1)
614 scan
->avl_balance
= 1;
615 next
->avl_balance
= 0;
617 else if (subroot
->avl_balance
== 1)
619 scan
->avl_balance
= 0;
620 next
->avl_balance
= -1;
624 scan
->avl_balance
= 0;
625 next
->avl_balance
= 0;
628 subroot
->avl_balance
= 0;
633 dir
= link_parent(root
, scan
, subroot
, parent
);
643 } /* AVL_RemNodeByAddress */
645 /*****************************************************************************
649 AROS_LH3I(struct AVLNode
*, AVL_RemNodeByKey
,
652 AROS_LHA(struct AVLNode
**, root
, A0
),
653 AROS_LHA(AVLKey
, key
, A1
), AROS_LHA(AVLKEYCOMP
, func
, A2
),
655 struct ExecBase
*, SysBase
, 144, Exec
)
657 Looks up a node in the tree by key, and removes it if it
661 Root - A pointer to a pointer to the root node of the AVL tree.
663 key - The key to search for.
665 func - An AVLKEYCOMP function used to compare the key and nodes
669 If the key was present in the tree, then a pointer to the node
670 for that key. Otherwise NULL if no such key existed in the
674 See AVL_RemNodeByAddress().
681 AVL_AddNode(), AVL_RemNodeByAddress()
684 ******************************************************************************/
688 struct AVLNode
*node
;
690 node
= AVL_FindNode(*root
, key
, func
);
693 node
= AVL_RemNodeByAddress(root
, node
);
698 } /* AVL_RemNodeByKey */
700 /*****************************************************************************
704 AROS_LH3I(struct AVLNode
*, AVL_FindNode
,
707 AROS_LHA(const struct AVLNode
*, Root
, A0
),
708 AROS_LHA(AVLKey
, key
, A1
), AROS_LHA(AVLKEYCOMP
, func
, A2
),
710 struct ExecBase
*, SysBase
, 145, Exec
)
712 Find an entry in the AVL tree by key.
715 Root - The root of the AVL tree.
717 key - The key to search.
719 func - The AVLKEYCOMP key comparision function for this tree.
722 A pointer to the node matching key if it exists in the
723 tree, or NULL if no such node exists.
728 node = (struct ExampleNode *)AVL_FindNode(root, "aros", ExampleKeyComp);
730 printf(" `%s' occurs %d times\n", node->key, node->count);
735 AVL_AddNode(), AVL_RemNodeByAddress(), AVL_FindNextNodeByAddress(),
736 AVL_FindPrevNodeByAddress()
739 ******************************************************************************/
743 struct AVLNode
*node
= (struct AVLNode
*)Root
;
746 while (node
!= NULL
&& (cmp
= func((struct AVLNode
*)node
, key
)) != 0)
748 node
= node
->avl_link
[cmp
< 0];
751 return (struct AVLNode
*)node
;
756 /*****************************************************************************
760 AROS_LH1I(struct AVLNode
*, AVL_FindPrevNodeByAddress
,
763 AROS_LHA(const struct AVLNode
*, Node
, A0
),
765 struct ExecBase
*, SysBase
, 146, Exec
)
767 Perform an inverse-order traversal to the previous node in the tree.
770 Node - The current node. The node must be present in the tree.
773 The next-least node in the tree, or NULL if Node was already
774 the lowest valued node in the tree.
777 This implementation uses a parent pointer to avoid needing
778 a stack or state to track it's current position in the tree.
780 Although this operation is typically O(1), in the worst case it
781 iterate the full depth of the tree - approximately 1.44Log(N).
784 ... inverse-order traversal of all nodes
785 node = (struct ExampleNode *)AVL_FindLastNode(root);
787 printf(" %s\n", node->key);
788 node = (struct ExampleNode *)AVL_FindPrevNodeByAddress(node);
791 ... inverse-order traversal of all nodes - with safe deletion
792 node = (struct ExampleNode *)AVL_FindLastNode(root);
793 prev = (struct ExampleNode *)AVL_FindPrevNodeByAddress(node);
795 printf(" %s\n", node->key);
797 if (DELETE_NODE(node))
798 AVL_RemNodeByAddress(&root, node);
801 prev = (struct ExampleNode *)AVL_FindPrevNodeByAddress(node);
807 AVL_AddNode(), AVL_RemNodeByAddress(), AVL_FindLastNode()
810 ******************************************************************************/
814 const struct AVLNode
*node
= (const struct AVLNode
*)Node
;
815 const struct AVLNode
*prev
;
817 prev
= node
->avl_link
[0];
823 prev
= prev
->avl_link
[1];
832 node
= node
->avl_parent
;
834 while (node
!= NULL
&& node
->avl_link
[1] != prev
);
837 return (struct AVLNode
*)node
;
840 } /* AVL_FindPrevNodeByAddress */
842 /*****************************************************************************
846 AROS_LH3I(struct AVLNode
*, AVL_FindPrevNodeByKey
,
849 AROS_LHA(const struct AVLNode
*, root
, A0
),
850 AROS_LHA(AVLKey
, key
, A1
), AROS_LHA(AVLKEYCOMP
, func
, A2
),
852 struct ExecBase
*, SysBase
, 147, Exec
)
854 Find the node matching the key, or if such a node does not exist,
855 then the node with the next-lowest value.
858 Root - The root of the AVL tree.
860 key - The key to search.
862 func - The AVLKEYCOMP key comparision function for this tree.
865 A pointer to the struct AVLNode which matches this key, or
866 if that key is not present in the tree, the next lowest node.
867 Or NULL if key is lower than the key of any node in the tree.
870 This is only O(1.44log(n)) in the worst case.
877 AVL_AddNode(), AVL_FindNextNodeByAddress(), AVL_FindLastNode()
880 ******************************************************************************/
884 struct AVLNode
*node
= (struct AVLNode
*)root
;
885 struct AVLNode
*lesser
= NULL
;
888 while (node
!= NULL
&& (cmp
= func((struct AVLNode
*)node
, key
)) != 0)
892 node
= node
->avl_link
[cmp
< 0];
895 return (struct AVLNode
*)(node
!= NULL
? node
: lesser
);
898 } /* AVL_FindPrevNodeByKey */
900 /*****************************************************************************
904 AROS_LH1I(struct AVLNode
*, AVL_FindNextNodeByAddress
,
907 AROS_LHA(const struct AVLNode
*, Node
, A0
),
909 struct ExecBase
*, SysBase
, 148, Exec
)
911 Perform an in-order traversal to the next node in the tree.
914 Node - The current node. The node must be present in the tree.
917 The next-greatest node in the tree, or NULL if Node was already
918 the highest valued node in the tree.
921 This implementation uses a parent pointer to avoid needing
922 a stack or state to track it's current position in the tree.
924 Although this operation is typically O(1), in the worst case it
925 iterate the full depth of the tree - approximately 1.44Log(N).
928 ... in-order traversal of all nodes
929 node = (struct ExampleNode *)AVL_FindFirstNode(root);
931 printf(" %s\n", node->key);
932 node = (struct ExampleNode *)AVL_FindNextNodeByAddress(node);
935 ... in-order traversal of all nodes - with safe deletion
936 node = (struct ExampleNode *)AVL_FindFirstNode(root);
937 next = (struct ExampleNode *)AVL_FindNextNodeByAddress(node);
939 printf(" %s\n", node->key);
941 if (DELETE_NODE(node))
942 AVL_RemNodeByAddress(&root, node);
945 next = (struct ExampleNode *)AVL_FindNextNodeByAddress(node);
951 AVL_AddNode(), AVL_RemNodeByAddress(), AVL_FindFirstNode()
954 ******************************************************************************/
958 const struct AVLNode
*node
= (const struct AVLNode
*)Node
;
959 const struct AVLNode
*next
;
961 next
= node
->avl_link
[1];
967 next
= node
->avl_link
[0];
969 while (next
!= NULL
);
976 node
= node
->avl_parent
;
978 while (node
!= NULL
&& node
->avl_link
[1] == next
);
981 return (struct AVLNode
*)node
;
984 } /* AVL_FindNextNodeByAddress */
986 /*****************************************************************************
990 AROS_LH3I(struct AVLNode
*, AVL_FindNextNodeByKey
,
993 AROS_LHA(const struct AVLNode
*, Root
, A0
),
994 AROS_LHA(AVLKey
, key
, A1
), AROS_LHA(AVLKEYCOMP
, func
, A2
),
996 struct ExecBase
*, SysBase
, 149, Exec
)
998 Find the node matching the key, or if such a node does not exist,
999 then the node with the next-highest value.
1002 Root - The root of the AVL tree.
1004 key - The key to search.
1006 func - The AVLKEYCOMP key comparision function for this tree.
1009 A pointer to the struct AVLNode which matches this key, or
1010 if that key is not present in the tree, the next highest node.
1011 Or NULL if key is higher than the key of any node in the tree.
1014 This is only O(1.44log(n)) in the worst case.
1021 AVL_AddNode(), AVL_FindNextNodeByAddress(), AVL_FindLastNode()
1024 ******************************************************************************/
1028 struct AVLNode
*node
= (struct AVLNode
*)Root
;
1029 struct AVLNode
*greater
= NULL
;
1032 while (node
!= NULL
&& (cmp
= func((struct AVLNode
*)node
, key
)) != 0)
1036 node
= node
->avl_link
[cmp
< 0];
1039 return (struct AVLNode
*)(node
!= NULL
? node
: greater
);
1042 } /* AVL_FindNextNodeByKey */
1044 /*****************************************************************************
1048 AROS_LH1I(struct AVLNode
*, AVL_FindFirstNode
,
1051 AROS_LHA(const struct AVLNode
*, Root
, A0
),
1053 struct ExecBase
*, SysBase
, 150, Exec
)
1055 Find the smallest node in an AVL tree.
1058 Root - The root node of the AVL tree.
1061 NULL if the tree is empty (i.e. Root is NULL), or the node
1062 which contains the least value in the tree as determined by
1063 the comparision function used to add the node.
1066 AVL trees are balanced but not minimal. This operation
1067 must iterate the full depth of the tree on one side -
1068 approximately 1.44Log(N).
1071 See AVL_FindNextNodeByAddress()
1076 AVL_AddNode(), AVL_FindNextNodeByAddress()
1079 ******************************************************************************/
1083 struct AVLNode
*node
= (struct AVLNode
*)Root
;
1086 while (node
->avl_link
[0] != NULL
)
1087 node
= node
->avl_link
[0];
1089 return (struct AVLNode
*)node
;
1092 } /* AVL_FindFirstNode */
1094 /*****************************************************************************
1098 AROS_LH1I(struct AVLNode
*, AVL_FindLastNode
,
1101 AROS_LHA(const struct AVLNode
*, Root
, A0
),
1103 struct ExecBase
*, SysBase
, 151, Exec
)
1105 Find the largest node in an AVL tree.
1108 Root - The root node of the AVL tree.
1111 NULL if the tree is empty (i.e. Root is NULL), or the node
1112 which contains the greatest value in the tree as determined by
1113 the comparision function used to add the node.
1116 AVL trees are balanced but not minimal. This operation
1117 must iterate the full depth of the tree on one side -
1118 approximately 1.44Log(N).
1121 See AVL_FindPrevNodeByAddress()
1126 AVL_AddNode(), AVL_FindPrevNodeByAddress()
1129 ******************************************************************************/
1133 struct AVLNode
*node
= (struct AVLNode
*)Root
;
1136 while (node
->avl_link
[1] != NULL
)
1137 node
= node
->avl_link
[1];
1139 return (struct AVLNode
*)node
;
1142 } /* AVL_FindLastNode */