|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Home : Math & Science : Computer Science Study Guides : Trees : Binary : Building a Binary Search Tree
Building a Binary Search Tree
In order to take advantage of the fast searching abilities of a binary
search tree, it is first necessary to put your data into this format.
For the following section, we will assume that we have the following
functions to access the data. In your programs this may mean reading
from a file or from standard input.
int data_remaining(void); int next_data(); The first is a boolean that returns true while data remains and the second
will supply the next piece of data. Realize that the data is coming in no
particular order (ie. it is not presorted).
We want to build the tree with the following algorithm. We will read in a
piece of data, find the appropriate place to add it into the tree (meaning
we'll find a leaf that could have this piece of data as a child) and then
add the data element in that spot.
First we will write a function that determines where the data element should
be added to the tree. The return from the function will be the memory
address where the data element should be stored. This means that if we find
that the appropriate storage location is the right child of tree t, we
would return &(t->right). The algorithm consists of walking left or
right down the tree according to whether the data element is greater than or
less than the data in the current node. We will also assume that the data is
all unique, so there is no chance of the same number appearing more than once.
It's possible to handle multiple instances of the same data element, but
we'll ignore this situation for simplicity's sake.
tree_t insertion_location(tree_t *t, int data)
{
if (t == NULL) {
return NULL;
}
tree_t holder;
/* Recursively find the insertion location. */
if (data < t->data) {
/*
* Search for an insertion location further down the tree.
* If one isn't found, the insertion location should be
* the left pointer of t.
*/
holder = insertion_location (t->left);
if(holder) {
return holder;
} else {
return &(t->left);
}
} else {
/*
* Search for an insertion location further down the tree.
* If one isn't found, the insertion location should be
* the right pointer of t.
*/
holder = insertion_location (t->right);
if(holder) {
return holder;
} else {
return &(t->right);
}
}
}
If insertion_location returns null, whatever tree was passed as the argument
should instead point to a new tree with that data element. Note that when
walking through the tree, if suffices to check if the number is less than the
data in the current node to determine whether it belongs in the left or the
right subtree.
Now that we have written the more complex recursive part, we simply need to
write the iterative function that calls the recursive one to build the tree.
tree_t *build_tree(void)
{
int data;
tree_t *t, *new_tree, *insert_point;
while (data_remaining()) {
data = next_data();
if((new_tree = new_tree(data)) == NULL) {
return NULL;
}
insert_point = insertion_location(t, data);
if (insert_point == NULL) {
t = new_tree;
} else {
*insert_point = new_tree;
}
}
return t;
}
Notice that whenever we call a function that returns dynamically allocated
memory, it is always necessary to check for the possibility that allocation
failed and returned a NULL pointer. The only time that insert_point will
be NULL is when ~insertion_location~ is called for the first time, with a
NULL pointer, that is, before there is anything in the tree.
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contact Us | Privacy Policy | Terms and Conditions | About
©2006 SparkNotes LLC, All Rights Reserved.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||