Binary Search Trees - Some Notes
We discussed the different ways to traverse a binary search tree (BST): level-order, in-order, pre-order, and post-order. It is important to know:
how to traverse a BST and list the nodes visited in these various orders | |
how to reconstruct a BST if a nodes and the order in which the tree was traversed is listed | |
how to write recursive code to perform the tree traversal in these orders |
Here, we will focus on inserting and deleting a node into a BST.
To insert a node into a BST, the following algorithm could be used:
if the tree is empty, insert the data as root | |
if the tree is not empty, take a new pointer that points at the root. |
if the node to be inserted is the same as the current node, stop - insertion failed. | |
if the node to be inserted is larger than the current node, and right child is not empty, change pointer to right child | |
if the node to be inserted is smaller than the current node, and left child is not empty, change pointer to left child |
First, look at the following tree below and insert the numbers 65, 35, 100, and 91 (if
possible).
Next, try to write some code that will insert a node into a BST. Recall the definition of
a node is:
To be a little more formal, here is the definition of a BST together with the insert method specification:
Here is the complete code for the insertion. This is only a suggestion, and there are several other, perhaps better, ways of doing this:
This code is fairly complicated, because it acually does two tasks in one: it first
searches for the element to be inserted, and if it did not find it, then it inserts it at
the appropriate positioin. Therefore, we should try to simplify the insertion by
introduction a separate function that searches for an element. Our insertion function can
then try to use that function instead of duplicating the search process.
Here is some code that searches for an element in a binary search tree. For input, it
takes a pointer to the root of the tree. When the procedure is finished, the pointer p
will point to the node containing the element to search for, or to null if the element can
not be found.
But, this function can not be used for our insertion routine, because to insert, we need to pretend to search for the node, and if the node can not be found, we need to have a pointer to the previous node considered. At that node the new element should be inserted as either right or left child. But the above function can be easily modified to deliver this pointer:
Now this function can be used by passing as input a pointer to the root of the tree. When the function finishes, and p points to null, it means that the element could not be found, and hence can be inserted. What's more, the node parent will point to the node where the new element can be inserted as either the right or left child.
Now, rewrite the insert method to use this new method FindNodes. You could follow this algorithm:
use FindNodes to search for the element | |
if element was found in the tree, report failure | |
else create a new node pnew containing the tree element and set the parent pointer of p to the new pointer pnew and report success | |
Note that if p is the root than parent is not valid |
Next, lets focus on deletion. Deleting a key from a BST is broken up into three distinct cases:
deleting a node with no children (i.e. a leaf) | |
deleting a node with only one child | |
deleting a node with two children |
You might find one of the following algorithms helpful:
if the node p is a leaf then: |
remove the node |
Determine if p is the right or left child of parent | |
Reset right or left pointer of parent to the non-empty child of p |
Find the right-most node in the left subtree of p, call it righty | |
Move righty's content to p | |
Reset the pointer of righty's parent to righty's left child |
Note that if p is the root than parent is not valid
We will not discuss the code for an actual deletion. Rather, you need to practice this
algorithm on trees that are printed. For example, a typical question on an exam would
be:
Draw the binary search tree after each operation. Each insertion and deletion operates
on the original tree, and the new tree is again a binary search tree.
a) Insert 65
b) Insert 35
c) Delete 70
d) Delete 60
e) Delete 50
f) First delete 50, then 45.
We will review these discussions on Monday, if necessary, together with a general review for the second exam.