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


GNU libavl 2.0.1

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

8.6 Insertion

It take a little more effort to insert a new node into a threaded BST than into an unthreaded one, but not much more. The only difference is that we now have to set up the new node's left and right threads to point to its predecessor and successor, respectively.

Fortunately, these are easy to figure out. Suppose that new node n is the right child of its parent p (the other case is symmetric). This means that p is n's predecessor, because n is the least node in p's right subtree. Moreover, n's successor is the node that was p's successor before n was inserted, that is to say, it is the same as p's former right thread.

Here's an example that may help to clear up the description. When new node 3 is inserted as the right child of 2, its left thread points to 2 and its right thread points where 2's right thread formerly did, to 4:

tbstins

The following code unifies the left-side and right-side cases using dir, which takes the value 1 for a right-side insertion, 0 for a left-side insertion. The side opposite dir can then be expressed simply as !dir.

 
void **
tbst_probe (struct tbst_table *tree, void *item)
{ struct tbst_node *p; /* Traverses tree to find insertion point. */ struct tbst_node *n; /* New node. */ int dir; /* Side of p on which n is inserted. */ assert (tree != NULL && item != NULL); &#60;@xref{\NODE\, , Step 1: Search TBST for insertion point.&#62;,255} &#60;@xref{\NODE\, , Step 2: Insert TBST node.&#62;,256} return &n-&#62;tbst_data; }
This code is included in @refalso{251

 
if (tree-&#62;tbst_root != NULL)
  for (p = tree-&#62;tbst_root; ; p = p-&#62;tbst_link[dir]) 
{ int cmp = tree-&#62;tbst_compare (item, p-&#62;tbst_data, tree-&#62;tbst_param); if (cmp == 0) return &p-&#62;tbst_data; dir = cmp > 0; if (p-&#62;tbst_tag[dir] == TBST_THREAD) break; } else
{ p = (struct tbst_node *) &tree-&#62;tbst_root; dir = 0; }
This code is included in @refalso{254

 
n = tree-&#62;tbst_alloc-&#62;libavl_malloc (tree-&#62;tbst_alloc, sizeof *n);
if (n == NULL)
  return NULL;
tree-&#62;tbst_count++;
n-&#62;tbst_data = item;
n-&#62;tbst_tag[0] = n-&#62;tbst_tag[1] = TBST_THREAD;
n-&#62;tbst_link[dir] = p-&#62;tbst_link[dir];
if (tree-&#62;tbst_root != NULL) 
{ p-&#62;tbst_tag[dir] = TBST_CHILD; n-&#62;tbst_link[!dir] = p; } else
n-&#62;tbst_link[1] = NULL; p-&#62;tbst_link[dir] = n;
This code is included in @refalso{254

See also: [ Knuth 1997], algorithm 2.3.1I.

Exercises:

1. What happens if we reverse the order of the final if statement above and the following assignment? [answer]


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

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