1 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN"[]>
5 <title>Generic AVL Tree Implementation (GAVL)</title>
9 <firstname>Pavel</firstname>
10 <surname>Pisa</surname>
13 <email>pisa@cmp.felk.cvut.cz</email>
21 <holder>Pavel Pisa</holder>
25 <para>Implementation of AVL tree with some interesting features.
26 All algorithms for insertion, deletion, traversal etc. are implemented without
27 function call recursion or tree node stacks. The only exception is routine to
28 check correctness of tree used for debugging purposes. The implementation has
29 more advantages. It can work with partially unbalanced trees with balance
30 factor (height difference) outside range <-1,1>. The balancing
31 subroutine is common for insertion and deletion. Provided macros enables
32 to build trees with strict item type checking which avoids necessity to use
33 type-casting from (void *).
42 <title>Introduction</title>
44 There are more concepts how to store data items sorted by some key values.
45 The most commonly used ones are:
48 <para>sorted conntinuous arrays of items or pointers to items</para>
51 <para>binary search trees (splash tree, AVL-tree, RB-tree)</para>
54 <para>more childs per node search trees (B-tree)</para>
59 The binary search trees are considered most efficient for in memory
60 operations when frequent tree updates are present. If update frequency
61 is very low, sorted arrays of pointers could be more efficient. If the
62 node retrieval operations are time consuming the n-nary search trees
66 The provided GAVL library tries to offer fast and API friendly
67 set of functions and macros usable for in-memory stored AVL trees
68 of user specified items. The tree node chaining informations
69 must be added to each stored item for holding of the tree node
70 topology. The GAVL library can use user specified field of items
71 or small malloced structure for holding of node chaining information.
74 The tree search, insert and delete functions can work with and enforce tree
75 with unique items or can be used in mode when more items with same
76 search key value are allowed. The balancing and other functions
77 are written such way, that they tolerate even degraded tree
78 which does not fulfill AVL tree definition. The operations do not
79 result in further degradation or program exceptions.
80 Even future tree operations tends to enhance balancing if the height
81 differences (balance factors) of degraded tree has been correctly updated.
87 <chapter id="gavlfunc">
88 <title>Functions Description</title>
89 <sect1><title>Generic AVL tree</title>
90 !F../../ulut/ul_gavl.h
91 !F../../ulut/ul_gavlprim.c
92 !F../../ulut/ul_gavl.c
94 <sect1><title>Custom AVL Tree Instances</title>
96 The provided macros allows to define all AVL tree
97 functions for tree with user defined root and item types.
98 The next defined function names are prefixed by custom selected
99 <replaceable>cust_prefix</replaceable>:
105 <funcsynopsis><funcprototype>
106 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_node2item</function></funcdef>
107 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
108 <paramdef>const gavl_node_t * <parameter>node</parameter></paramdef>
109 </funcprototype></funcsynopsis>
113 Conversion from AVL tree node to user custom defined item
120 <funcsynopsis><funcprototype>
121 <funcdef><replaceable>cust_key_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_node2key </function></funcdef>
122 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
123 <paramdef>const gavl_node_t * <parameter>node</parameter></paramdef>
124 </funcprototype></funcsynopsis>
128 Conversion from AVL tree node to pointer to defined ordering key
134 <funcsynopsis><funcprototype>
135 <funcdef>int <function><replaceable>cust_prefix</replaceable>_search_node </function></funcdef>
136 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
137 <paramdef>const <replaceable>cust_item_t</replaceable> * <parameter>key</parameter></paramdef>
138 <paramdef>gavl_node_t ** <parameter>nodep</parameter></paramdef>
139 </funcprototype></funcsynopsis>
143 Search for node or place for node by key
149 <funcsynopsis><funcprototype>
150 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_find </function></funcdef>
151 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
152 <paramdef>const <replaceable>cust_key_t</replaceable> * <parameter>key</parameter></paramdef>
153 </funcprototype></funcsynopsis>
157 Pointer to item with key value or <constant>NULL</constant>
163 <funcsynopsis><funcprototype>
164 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_find_first </function></funcdef>
165 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
166 <paramdef>const <replaceable>cust_key_t</replaceable> * <parameter>key</parameter></paramdef>
167 </funcprototype></funcsynopsis>
171 Same as above, but first matching item is found.
177 <funcsynopsis><funcprototype>
178 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_find_after </function></funcdef>
179 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
180 <paramdef>const <replaceable>cust_key_t</replaceable> * <parameter>key</parameter></paramdef>
181 </funcprototype></funcsynopsis>
185 Finds the first item with key value higher than value pointed
186 by <parameter>key</parameter> or returns <constant>NULL</constant>.
192 <funcsynopsis><funcprototype>
193 <funcdef>int <function><replaceable>cust_prefix</replaceable>_insert </function></funcdef>
194 <paramdef><replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
195 <paramdef><replaceable>cust_item_t</replaceable> * <parameter>item</parameter></paramdef>
196 </funcprototype></funcsynopsis>
200 Insert new item into AVL tree. If the operation is successful
201 positive value is returned. If key with same key value already
202 exists negative value is returned
208 <funcsynopsis><funcprototype>
209 <funcdef>int <function><replaceable>cust_prefix</replaceable>_delete_node </function></funcdef>
210 <paramdef><replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
211 <paramdef>gavl_node_t * <parameter>node</parameter></paramdef>
212 </funcprototype></funcsynopsis>
216 Deletes/unlinks node from custom AVL tree
222 <funcsynopsis><funcprototype>
223 <funcdef>int <function><replaceable>cust_prefix</replaceable>_delete </function></funcdef>
224 <paramdef><replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
225 <paramdef><replaceable>cust_item_t</replaceable> * <parameter>item</parameter></paramdef>
226 </funcprototype></funcsynopsis>
230 Deletes/unlinks item from custom AVL tree
236 <funcsynopsis><funcprototype>
237 <funcdef>gavl_node_t * <function><replaceable>cust_prefix</replaceable>_first_node </function></funcdef>
238 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
239 </funcprototype></funcsynopsis>
243 Returns the first node or <constant>NULL</constant> if the tree is empty
249 <funcsynopsis><funcprototype>
250 <funcdef>gavl_node_t * <function><replaceable>cust_prefix</replaceable>_last_node </function></funcdef>
251 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
252 </funcprototype></funcsynopsis>
256 Returns last node or <constant>NULL</constant> if the tree is empty
263 <funcsynopsis><funcprototype>
264 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_first</function></funcdef>
265 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
266 </funcprototype></funcsynopsis>
270 Returns pointer to the first item of the tree or <constant>NULL</constant>
277 <funcsynopsis><funcprototype>
278 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_last</function></funcdef>
279 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
280 </funcprototype></funcsynopsis>
284 Returns pointer to last item of the tree or <constant>NULL</constant>
291 <funcsynopsis><funcprototype>
292 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_next</function></funcdef>
293 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
294 <paramdef>const <replaceable>cust_item_t</replaceable> * <parameter>item</parameter></paramdef>
295 </funcprototype></funcsynopsis>
299 Returns pointer to next item of the tree or <constant>NULL</constant>
300 if there is no more items
307 <funcsynopsis><funcprototype>
308 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_prev</function></funcdef>
309 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
310 <paramdef>const <replaceable>cust_item_t</replaceable> * <parameter>item</parameter></paramdef>
311 </funcprototype></funcsynopsis>
315 Returns pointer to previous item of the tree or <constant>NULL</constant>
316 if there is no more items
323 <funcsynopsis><funcprototype>
324 <funcdef>int <function><replaceable>cust_prefix</replaceable>_is_empty </function></funcdef>
325 <paramdef>const <replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
326 </funcprototype></funcsynopsis>
330 Returns non-zero value if there is no node in the tree
337 <funcsynopsis><funcprototype>
338 <funcdef><replaceable>cust_item_t</replaceable> * <function><replaceable>cust_prefix</replaceable>_cut_first </function></funcdef>
339 <paramdef><replaceable>cust_root_t</replaceable> * <parameter>root</parameter></paramdef>
340 </funcprototype></funcsynopsis>
344 Returns the first item or <constant>NULL</constant> if the tree is empty.
345 The returned item is unlinked from the tree without tree rebalance
356 <refentrytitle><phrase id="API-GAVL-CUST-NODE-INT-IMP">GAVL_CUST_NODE_INT_IMP</phrase></refentrytitle>
359 <refname>GAVL_CUST_NODE_INT_IMP</refname>
361 Implementation of new custom tree with internal node
365 <title>Synopsis</title>
366 <funcsynopsis><funcprototype>
367 <funcdef> <function>GAVL_CUST_NODE_INT_IMP </function></funcdef>
368 <paramdef> <parameter>cust_prefix</parameter></paramdef>
369 <paramdef> <parameter>cust_root_t</parameter></paramdef>
370 <paramdef> <parameter>cust_item_t</parameter></paramdef>
371 <paramdef> <parameter>cust_key_t</parameter></paramdef>
372 <paramdef> <parameter>cust_root_node</parameter></paramdef>
373 <paramdef> <parameter>cust_item_node</parameter></paramdef>
374 <paramdef> <parameter>cust_item_key</parameter></paramdef>
375 <paramdef> <parameter>cust_cmp_fnc</parameter></paramdef>
376 </funcprototype></funcsynopsis>
379 <title>Arguments</title>
382 <term><parameter>cust_prefix</parameter></term>
385 defines prefix for builded function names
390 <term><parameter>cust_root_t</parameter></term>
393 user defined structure type of root of the tree
398 <term><parameter>cust_item_t</parameter></term>
401 user defined structure type of items stored in the tree
406 <term><parameter>cust_key_t</parameter></term>
409 type of the key used for sorting of the items
414 <term><parameter>cust_root_node</parameter></term>
417 the field of the root structure pointing to the tree root node
422 <term><parameter>cust_item_node</parameter></term>
425 the field of item structure used for chaining of items
430 <term><parameter>cust_item_key</parameter></term>
433 the key field of item structure defining order of items
438 <term><parameter>cust_cmp_fnc</parameter></term>
441 the keys compare function
448 <title>Description</title>
450 There are two macros designed for building custom AVL trees. The macro
451 <constant>GAVL_CUST_NODE_INT_DEC</constant> declares functions for custom tree manipulations
452 and is intended for use in header files.
453 The macro <constant>GAVL_CUST_NODE_INT_IMP</constant> builds implementations for non-inlined
454 functions declared by <constant>GAVL_CUST_NODE_INT_DEC</constant>. The <parameter>cust_cmp_fnc</parameter> is used
455 for comparison of item keys in the search and insert functions. The types
456 of two input arguments of <parameter>cust_cmp_fnc</parameter> functions must correspond
457 with <parameter>cust_key_t</parameter> type. Return value should be positive for case when
458 the first pointed key value is greater then second, negative for reverse
459 case and zero for equal pointed values.
468 <chapter id="gavlexample">
469 <title>Examples of GAVL Usage</title>
470 <sect1><title>Generic AVL Tree</title>
472 This chapter describes use of generic AVL tree. This tree has advantage,
473 that same functions could operate with any user provided items, but
474 operations return type is <type>void</type>* and needs type-casting to
477 <programlisting>#include <malloc.h>
478 #include "ul_gavl.h"</programlisting>
481 The above code fragment includes basic GAVL declarations.
484 <programlisting>typedef struct test1_item {
486 /* more user data ... */
487 } test1_item_t;</programlisting>
490 New item type is declared. Type have to contain or be connected to
491 some key value. The <type>integer</type> number
492 <structfield>my_val</structfield> will be used as key value in this example.
493 The tree root instance definition follows.
496 <programlisting>gavl_root_t test1_tree={
499 .key_offs = UL_OFFSETOF(test1_item_t, my_val),
500 .cmp_fnc = gavl_cmp_int
504 The field <structfield>root_node</structfield> have to be initialized to
505 <constant>NULL</constant>.
506 The value -1 for the <structfield>node_offs</structfield> field directs
507 GAVL functions to allocate external node structure for each inserted item.
508 The macro <constant>UL_OFFSETOF</constant> computes offset of
509 <structfield>my_val</structfield> field in <type>test1_item_t</type>
510 item. The last assignment select one of predefined functions for
511 key values comparison.
515 Almost same declarations and definitions could be used if the node
516 chaining structure is contained inside item structure. That is shown in
517 the next code fragments.
520 <programlisting>typedef struct test2_item {
523 /* more user data ... */
524 } test2_item_t;</programlisting>
527 The item declaration contains field with <type>gavl_node_t</type> type
528 in this case. This field is used for storage of tree topology information.
531 <programlisting>gavl_root_t test2_tree={
533 .node_offs = UL_OFFSETOF(test2_item_t, my_node),
534 .key_offs = UL_OFFSETOF(test2_item_t, my_val),
535 .cmp_fnc = gavl_cmp_int
539 The field <structfield>node_offs</structfield> contains offset of the
540 node structure inside item now. Next fragments are part of the function
541 working with defined tree. There would be no difference in the functions
542 calls for items with external nodes.
545 <programlisting> cust2_item_t *item;
547 gavl_node_t *node;</programlisting>
550 Declare some local variables first. Insert 100 items into tree then.
553 <programlisting> for(i=0;i<items_cnt;i++){
554 item=malloc(sizeof(test2_item_t));
556 if(gavl_insert(&test2_tree,item,0)<0)
557 printf("gavl_insert error\n");
561 The tree is expected to store items with unique key values.
562 If more items with same key values should be allowed, then the
563 value of <parameter>mode</parameter> parameter in <function>gavl_insert</function>
564 function call have to be changed from 0 to <constant>GAVL_FAFTER</constant>.
567 <programlisting> for(i=0;i<102;i++){
568 if(!(item=(cust2_item_t *)gavl_find(&test2_tree,&i)))
569 printf("no item %d\n",i);
571 if(item->my_val!=i)
572 printf("gavl_find mismatch\n");
576 Some test of retrieving item corresponding to specified key.
577 The tree in order traversal is in the next code sample.
580 <programlisting> node=gavl_first_node(&test2_tree)
582 item=(cust2_item_t *)gavl_node2item(&test2_tree,node);
583 /* do something with item
584 * insert and delete allowed there except delete of the actual item
586 node=gavl_next_node(node);
587 /* do something with item
588 * insert and delete allowed there except delete of next item
593 Example of the item deletion is in the next fragment.
594 The function <function>gavl_delete</function>
595 guarantees that trial of deleting item, which is not part of the tree,
596 is detected and negative value is returned. There is one prerequisite
597 for this behavior for items with internal nodes that have never been
598 part of any tree. The field <structfield>parent</structfield>
599 of node structure stored in the item have to be initialized to
600 <constant>NULL</constant> value.
603 <programlisting> for(i=0;i<80;i++){
604 if(!(item=(cust2_item_t *)gavl_find(&test2_tree,&i)))
606 if(gavl_delete(&test2_tree,item)<0)
607 printf("gavl_delete error\n");
612 The function <function>gavl_cut_first</function> can significantly simplify
613 deletion of all nodes of the tree without need of traversal over the tree.
614 This function does not rebalance the tree, but keeps tree consistent.
617 <programlisting> while((item=(cust2_item_t *)gavl_cut_first(&test2_tree))!=NULL)
618 free(item);</programlisting>
621 <sect1><title>Customized AVL Tree</title>
623 The function templates are provided for faster and type-safe
624 custom tree definition and manipulation. These templates expect
625 user defined items with internal node structures and key comparison
626 function with key pointer input parameters. The type of these
627 parameters is required to be pointer to the key type.
630 Next code fragment is intended to be part of the declarations
631 of user defined custom tree and items for some data storage
632 purpose. The header with these definitions should be included
633 from all modules directly working with specified tree.
636 <programlisting>#include "ul_gavl.h"
638 typedef int cust_key_t;
640 typedef struct cust2_item {
643 /* more user item data ... */
646 typedef struct cust2_root {
647 gavl_node_t *my_root;
648 /* more user root/tree data ... */
651 int cust_cmp_fnc(cust_key_t *a, cust_key_t *b);</programlisting>
654 As can be seen from above code fragment, the key field with user declared
655 type (<type>cust_key_t</type>) and internal node structure are required
656 for items. The only one field with type <type>gavl_node_t</type>* is required
657 for the custom tree root structure.
660 The use of the macro <constant>GAVL_CUST_NODE_INT_DEC</constant> declares
661 all tree manipulation functions for the custom tree. The function names are
662 prefixed by prefix specified as the first parameter of macro invocation.
663 This declaration can be included in user header files as well.
666 <programlisting>GAVL_CUST_NODE_INT_DEC(cust2, cust2_root_t, cust2_item_t, cust2_key_t,\
667 my_root, my_node, my_val, cust_cmp_fnc)</programlisting>
670 The implementation of the custom tree functions is realized
671 by use of macro <constant>GAVL_CUST_NODE_INT_IMP</constant> with same
672 parameters as for <constant>GAVL_CUST_NODE_INT_DEC</constant> macro.
675 <programlisting>#include "ul_gavlcust.h"
677 GAVL_CUST_NODE_INT_IMP(cust2, cust2_root_t, cust2_item_t, cust2_key_t,\
678 my_root, my_node, my_val, cust_cmp_fnc)
680 cust2_root_t cust2_tree;</programlisting>
683 Static tree root instance is included at last line of above code fragment as well.
686 The next sample function for the custom tree shows same operation
687 as have been described for generic tree.
690 <programlisting>void test_cust_tree(void)
696 for(i=1;i<=100;i++){
697 item=malloc(sizeof(cust2_item_t));
699 if(cust2_insert(&cust2_tree,item)<0)
700 printf("cust2_insert error\n");
704 printf("Custom tree cust2:\n");
705 for(item=cust2_first(&cust2_tree);item;item=cust2_next(&cust2_tree,item))
706 printf("%d ",item->my_val);
707 printf("\n");
709 /* delete part of the tree */
710 for(i=1;i<=80;i++){
711 item=cust2_find(&cust2_tree,&i);
712 if(cust2_delete(&cust2_tree,item)<0)
713 printf("cust2_delete error\n");
717 /* traverse in reverse order */
718 printf("Custom tree cust2:\n");
719 for(item=cust2_last(&cust2_tree);item;item=cust2_prev(&cust2_tree,item))
720 printf("%d ",item->my_val);
721 printf("\n");
723 /* delete all remaining items */
724 while((item=cust2_cut_first(&cust2_tree))!=NULL)
733 <title>A TeX Equation</title>
735 <imageobject role="html">
736 <imagedata fileref="texmath.png" format="PNG">
738 <textobject role="tex"><phrase>$C = \alpha + \beta Y^{\gamma}
739 + \epsilon$</phrase></textobject>
744 <chapter id="gavlalg">
745 <title>Used Algorithms Background</title>
746 <sect1><title>Tree Balancing Operations</title>
748 This section describes used algorithms for keeping
752 <!-- ***************************************************** -->
754 <para>Next convention is used for height and balance computations for node
760 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
763 </inlineequation>. The height of subtree starting at
769 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
772 </inlineequation> is labeled as
774 <alt>$x=height(\textrm{X})$
778 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
781 </inlineequation>. Height difference (balance factor) for node
787 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
790 </inlineequation> is labeled as
792 <alt>$\Delta x=height(left(\textrm{X}))-height(right(\textrm{X}))$
796 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
802 <title>Tree Balancing Case 1</title>
805 <title>Tree balancing case 1</title>
808 <imagedata align="center" fileref="fig/gavl_t11.pdf" format="EPS" scale="75" >
811 <imagedata align="center" fileref="fig/gavl_t11.gif" format="GIF" scale="75" >
813 <caption><para>Before operation</para></caption>
817 <imagedata align="center" fileref="fig/gavl_t12.pdf" format="EPS" scale="75" >
820 <imagedata align="center" fileref="fig/gavl_t12.gif" format="GIF" scale="75" >
822 <caption><para>After operation</para></caption>
828 <alt>\begin{eqnarray*}
829 \Delta s & = & n-b\qquad \geq 2\\
830 \Delta n & = & a-p\qquad \geq 0
836 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
839 </equation> The height of subtree
845 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
848 </inlineequation> is defined by highest branch, which is branch grovinggrowing from node
854 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
857 </inlineequation>. This leads to next equations.
859 <alt>\begin{eqnarray*}
860 n & = & a+1\\
861 s & = & a+2\\
862 p & = & a-\Delta n\\
863 b & = & a+1-\Delta s
869 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
872 </equation>The height of branches
878 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
881 </inlineequation> and
887 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
890 </inlineequation> is marked as
896 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
899 </inlineequation> and
905 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
908 </inlineequation> after balancing.
910 <alt>\begin{eqnarray*}
911 \Delta s1 & = & p-b\\
912 \Delta n1 & = & a-s1
918 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
923 <alt>\begin{eqnarray*}
924 s1 & = & \max (p,b)+1\\
925 s1 & = & \max (a-\Delta n,a+1-\Delta s)+1\\
926 s1 & = & a+1+\max (-\Delta n,1-\Delta s)\\
927 s1 & = & a+1-\min (\Delta n,\Delta s-1)
933 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
938 <alt>\begin{eqnarray*}
939 \Delta s1 & = & a-\Delta n-a-1+\Delta s\\
940 \Delta s1 & = & \Delta s-\Delta n-1\\
941 \Delta n1 & = & a-a-1+\min (\Delta n,\Delta s-1)\\
942 \Delta n1 & = & \min (\Delta n-1,\Delta s-2)\\
943 \Delta n1 & = & \left\langle \begin{array}{cc}
944 \Delta n-1 & \qquad \Delta s\geq \Delta n+1\\
945 \Delta s-2 & \qquad \Delta s\leq \Delta n+1\end{array}
952 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
955 </equation>Because balancing in case 1 does not guarantee that new tree has lower height than original tree, it is necessary to compute tree height change (tree height lowering).
957 <alt>\begin{eqnarray*}
958 s-n1 & = & s-(\max (a,s1)+1)\\
959 & = & a+2-(\max (a,a+1+\max (-\Delta n,1-\Delta s))+1)\\
960 & = & 1-\max (0,\max (1-\Delta n,2-\Delta s))\\
961 & = & \min (1,\Delta n,\Delta s-1)\qquad \Delta n\geq 0,\Delta s\geq 2\\
962 & = & \min (1,\Delta n)\\
963 s-n1 & = & \left\langle \begin{array}{cc}
964 1 & \qquad \Delta n\neq 0\\
965 0 & \qquad \Delta n=1\end{array}
972 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
975 </equation></para></sect2>
976 <sect2><title>Tree Balancing Case 2</title>
979 <title>Tree balancing case 2</title>
982 <imagedata align="center" fileref="fig/gavl_t21.pdf" format="EPS" scale="75" >
985 <imagedata align="center" fileref="fig/gavl_t21.gif" format="GIF" scale="75" >
987 <caption><para>Before operation</para></caption>
991 <imagedata align="center" fileref="fig/gavl_t22.pdf" format="EPS" scale="75" >
994 <imagedata align="center" fileref="fig/gavl_t22.gif" format="GIF" scale="75" >
996 <caption><para>After operation</para></caption>
1000 <para>This case has advantage, that it reduces tree height for all node height combinations. Tree height is given by branch
1006 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1008 </inlinemediaobject>
1015 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1017 </inlinemediaobject>
1018 </inlineequation> or
1024 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1026 </inlinemediaobject>
1033 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1035 </inlinemediaobject>
1038 <alt>\begin{eqnarray*}
1039 \Delta s & = & n-d\qquad \geq 2\\
1040 \Delta n & = & a-p\qquad \leq -1
1046 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1051 <alt>\begin{eqnarray*}
1052 n & = & p+1\\
1053 s & = & p+2\\
1054 d & = & p+1-\Delta s\\
1055 a & = & p+\Delta n
1061 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1066 <alt>\begin{eqnarray*}
1067 \textrm{for}\, b\geq c\qquad c & = & b-\Delta p\qquad p=b+1\\
1068 \textrm{for}\, c\geq b\qquad b & = & c+\Delta p\qquad p=c+1
1074 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1083 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1085 </inlinemediaobject>
1086 </inlineequation> then the height differences
1092 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1094 </inlinemediaobject>
1101 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1103 </inlinemediaobject>
1104 </inlineequation> and
1110 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1112 </inlinemediaobject>
1113 </inlineequation> for nodes
1119 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1121 </inlinemediaobject>
1128 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1130 </inlinemediaobject>
1131 </inlineequation> and
1137 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1139 </inlinemediaobject>
1140 </inlineequation> of the balanced tree can be computed from next equations.
1142 <alt>\begin{eqnarray*}
1143 b\geq c & , & \Delta p\geq 0\\
1144 n1 & = & b+1\\
1145 p1 & = & b+2\\
1146 s1 & = & \max (c,d)+1=\max (b-\Delta p,b+2-\Delta s)+1\\
1147 \Delta s1 & = & c-d=b-\Delta p-b-2+\Delta s\\
1148 \Delta s1 & = & \Delta s-2-\Delta p\\
1149 \Delta n1 & = & a-b=b+1+\Delta n-b\\
1150 \Delta n1 & = & \Delta n+1\\
1151 \Delta p1 & = & n1-s1=b+1-\max (b-\Delta p,b+2-\Delta s)-1\\
1152 \Delta p1 & = & \min (\Delta p,\Delta s-2)\qquad \Delta p\geq 0,\Delta s\geq 2
1158 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1167 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1169 </inlinemediaobject>
1170 </inlineequation> then the height differences
1176 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1178 </inlinemediaobject>
1185 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1187 </inlinemediaobject>
1188 </inlineequation> and
1194 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1196 </inlinemediaobject>
1197 </inlineequation> for nodes
1203 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1205 </inlinemediaobject>
1212 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1214 </inlinemediaobject>
1215 </inlineequation> and
1221 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1223 </inlinemediaobject>
1224 </inlineequation> of the balanced tree can be computed from next equations.
1226 <alt>\begin{eqnarray*}
1227 c\geq b & , & \Delta p\leq 0\\
1228 s1 & = & c+1\\
1229 p1 & = & c+2\\
1230 n1 & = & \max (a,b)+1=\max (c+1+\Delta n,c+\Delta p)+1\\
1231 \Delta s1 & = & c-d=c-c-2+\Delta s\\
1232 \Delta s1 & = & \Delta s-2\\
1233 \Delta n1 & = & a-b=c+1+\Delta n-c-\Delta p\\
1234 \Delta n1 & = & \Delta n+1-\Delta p\\
1235 \Delta p1 & = & n1-s1=\max (c+1+\Delta n,c+\Delta p)+1-c-1\\
1236 \Delta p1 & = & \max (\Delta n,\Delta s-1)\qquad \Delta n\leq -1,\Delta p\leq 0
1242 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1245 </equation></para></sect2>
1247 <sect1><title>Height of the AVL Tree</title><para>Minimal number of nodes
1253 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1255 </inlinemediaobject>
1256 </inlineequation> can be computed recursively.
1259 T(h)=T(h-1)+T(h-2)+1,\, T(0)=0,\, T(1)=1\]
1264 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1267 </equation>1, 2, 4, 7, 12, 20, 33, 54, 88, 143, 232, 376, 609, 986</para><para>
1270 T(h)=\frac{1}{\sqrt{5}}\left(\frac{1+\sqrt{5}}{2}\right)^{(h+2)}-1\]
1275 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1281 T(h)=\frac{1}{\sqrt{5}}\, 2^{(h+2)\, log_{2}\left(\frac{1+\sqrt{5}}{2}\right)}-1\]
1286 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1292 h=\left(log_{2}(T+1)-log_{2}\left(\frac{1}{\sqrt{5}}\right)\right)log_{2}^{-1}\left(\frac{1+\sqrt{5}}{2}\right)-2\]
1297 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1303 log_{2}^{-1}\left(\frac{1+\sqrt{5}}{2}\right)=1.44042\]
1308 <imagedata fileref="img/gavl_eq1.gif" format="GIF">
1311 </equation></para><para>An AVL tree with n nodes has height between log2 (n + 1) and 1.44 * log2 (n + 2) - 0.328. An AVL tree with height h has between pow (2, (h + .328) / 1.44) - 1 and pow (2, h) - 1 nodes.</para><para>A red-black tree with n nodes has height at least log2 (n + 1) but no more than 2 * log2 (n + 1). A red-black tree with height h has at least pow (2, h / 2) - 1 nodes but no more than pow (2, h) - 1. </para>
1313 <!-- ***************************************************** -->