www.delorie.com/gnu/docs/avl/libavl_108.html   search  
 
Buy GNU books!


GNU libavl 2.0.1

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

6.6 Traversal

Traversal is largely unchanged from BSTs. However, we can be confident that the tree won't easily exceed the maximum stack height, because of the AVL balance condition, so we can omit checking for stack overflow.

 
&#60;@xref{\NODE\, , BST traverser refresher; bst =>.&#62; avl,62}
&#60;@xref{\NODE\, , BST traverser null initializer; bst =>.&#62; avl,64}
&#60;@xref{\NODE\, , AVL traverser least-item initializer.&#62;,180}
&#60;@xref{\NODE\, , AVL traverser greatest-item initializer.&#62;,181}
&#60;@xref{\NODE\, , AVL traverser search initializer.&#62;,182}
&#60;@xref{\NODE\, , AVL traverser insertion initializer.&#62;,179}
&#60;@xref{\NODE\, , BST traverser copy initializer; bst =>.&#62; avl,69}
&#60;@xref{\NODE\, , AVL traverser advance function.&#62;,183}
&#60;@xref{\NODE\, , AVL traverser back up function.&#62;,184}
&#60;@xref{\NODE\, , BST traverser current item function; bst =>.&#62; avl,74}
&#60;@xref{\NODE\, , BST traverser replacement function; bst =>.&#62; avl,75}
This code is included in @refalso{145

We do need to make a new implementation of the insertion traverser initializer. Because insertion into an AVL tree is so complicated, we just write this as a wrapper to avl_probe(). There probably wouldn't be much of a speed improvement by inlining the code anyhow:

 
void *
avl_t_insert (struct avl_traverser *trav, struct avl_table *tree, void *item)
{ void **p; assert (trav != NULL && tree != NULL && item != NULL); p = avl_probe (tree, item); if (p != NULL)
{ trav-&#62;avl_table = tree; trav-&#62;avl_node = ((struct avl_node *)
((char *) p - offsetof (struct avl_node, avl_data))); trav-&#62;avl_generation = tree-&#62;avl_generation - 1; return *p; }
else
{ avl_t_init (trav, tree); return NULL; } }
This code is included in @refalso{178

We will present the rest of the modified functions without further comment.

 
void *
avl_t_first (struct avl_traverser *trav, struct avl_table *tree)
{ struct avl_node *x; assert (tree != NULL && trav != NULL); trav-&#62;avl_table = tree; trav-&#62;avl_height = 0; trav-&#62;avl_generation = tree-&#62;avl_generation; x = tree-&#62;avl_root; if (x != NULL) while (x-&#62;avl_link[0] != NULL)
{ assert (trav-&#62;avl_height < AVL_MAX_HEIGHT); trav-&#62;avl_stack[trav-&#62;avl_height++] = x; x = x-&#62;avl_link[0]; } trav-&#62;avl_node = x; return x != NULL ? x-&#62;avl_data : NULL; }
This code is included in @refalso{178

 
void *
avl_t_last (struct avl_traverser *trav, struct avl_table *tree)
{ struct avl_node *x; assert (tree != NULL && trav != NULL); trav-&#62;avl_table = tree; trav-&#62;avl_height = 0; trav-&#62;avl_generation = tree-&#62;avl_generation; x = tree-&#62;avl_root; if (x != NULL) while (x-&#62;avl_link[1] != NULL)
{ assert (trav-&#62;avl_height < AVL_MAX_HEIGHT); trav-&#62;avl_stack[trav-&#62;avl_height++] = x; x = x-&#62;avl_link[1]; } trav-&#62;avl_node = x; return x != NULL ? x-&#62;avl_data : NULL; }
This code is included in @refalso{178

 
void *
avl_t_find (struct avl_traverser *trav, struct avl_table *tree, void *item)
{ struct avl_node *p, *q; assert (trav != NULL && tree != NULL && item != NULL); trav-&#62;avl_table = tree; trav-&#62;avl_height = 0; trav-&#62;avl_generation = tree-&#62;avl_generation; for (p = tree-&#62;avl_root; p != NULL; p = q)
{ int cmp = tree-&#62;avl_compare (item, p-&#62;avl_data, tree-&#62;avl_param); if (cmp < 0)
q = p-&#62;avl_link[0]; else if (cmp > 0)
q = p-&#62;avl_link[1]; else /* cmp == 0 */
{ trav-&#62;avl_node = p; return p-&#62;avl_data; } assert (trav-&#62;avl_height < AVL_MAX_HEIGHT); trav-&#62;avl_stack[trav-&#62;avl_height++] = p; } trav-&#62;avl_height = 0; trav-&#62;avl_node = NULL; return NULL; }
This code is included in @refalso{178

 
void *
avl_t_next (struct avl_traverser *trav)
{ struct avl_node *x; assert (trav != NULL); if (trav-&#62;avl_generation != trav-&#62;avl_table-&#62;avl_generation) trav_refresh (trav); x = trav-&#62;avl_node; if (x == NULL)
{ return avl_t_first (trav, trav-&#62;avl_table); }
else if (x-&#62;avl_link[1] != NULL)
{ assert (trav-&#62;avl_height < AVL_MAX_HEIGHT); trav-&#62;avl_stack[trav-&#62;avl_height++] = x; x = x-&#62;avl_link[1]; while (x-&#62;avl_link[0] != NULL)
{ assert (trav-&#62;avl_height < AVL_MAX_HEIGHT); trav-&#62;avl_stack[trav-&#62;avl_height++] = x; x = x-&#62;avl_link[0]; } }
else
{ struct avl_node *y; do
{ if (trav-&#62;avl_height == 0)
{ trav-&#62;avl_node = NULL; return NULL; } y = x; x = trav-&#62;avl_stack[--trav-&#62;avl_height]; }
while (y == x-&#62;avl_link[1]); } trav-&#62;avl_node = x; return x-&#62;avl_data; }
This code is included in @refalso{178

 
void *
avl_t_prev (struct avl_traverser *trav)
{ struct avl_node *x; assert (trav != NULL); if (trav-&#62;avl_generation != trav-&#62;avl_table-&#62;avl_generation) trav_refresh (trav); x = trav-&#62;avl_node; if (x == NULL)
{ return avl_t_last (trav, trav-&#62;avl_table); }
else if (x-&#62;avl_link[0] != NULL)
{ assert (trav-&#62;avl_height < AVL_MAX_HEIGHT); trav-&#62;avl_stack[trav-&#62;avl_height++] = x; x = x-&#62;avl_link[0]; while (x-&#62;avl_link[1] != NULL)
{ assert (trav-&#62;avl_height < AVL_MAX_HEIGHT); trav-&#62;avl_stack[trav-&#62;avl_height++] = x; x = x-&#62;avl_link[1]; } }
else
{ struct avl_node *y; do
{ if (trav-&#62;avl_height == 0)
{ trav-&#62;avl_node = NULL; return NULL; } y = x; x = trav-&#62;avl_stack[--trav-&#62;avl_height]; }
while (y == x-&#62;avl_link[0]); } trav-&#62;avl_node = x; return x-&#62;avl_data; }
This code is included in @refalso{178

Exercises:

1. Explain the meaning of this ugly expression, used in avl_t_insert():

 

[answer]


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster   donations   bookstore     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003