Lab - Binary Search Trees

Overview

One use of trees is a way to organize a set of ordered keys to allow for efficient searches. A binary search tree is a binary tree T such that each internal node v of T stores an item with key k such that:

Searching for a key

Your first task will be to write code which implements a search for a key in this tree (though we give you an outline of this code below). You might quickly notice that the property which defines a binary search tree leads quite directly to a recursive search algorithm. If you are looking in a tree for a given key, you may start at the root. If that position contains the desired key, you have found it. If not, you might ask where else in the tree the desired key might be. If the desired key is less than the key at the root, then you only need to search the left subtree. Of course, if that left subtree is empty, then you may give up on your search. Similarly, if the desired key is greater than the key at the root, then you only need to search the right subtree, assuming such a tree is non-empty.

Your goal is to implement the routine search1(int k, BinaryTree T) in the file Search.java which we have provided. This routine is to search tree T for key k. If the search is successful, the routine should return a Position of the tree which contains a value equal to k. If no such position exists, your routine should return null. The tree T is defined so that each internal node contains an integer value. External nodes do not contain any value and are used as sentinels. You may get the int value stored at an internal node by calling getKey(Position p).

Viewing this process recursively is quite natural. In terms of implementation however, there is one catch. The method search1 expects a key and a BinaryTree T as parameters. If you call a method such as T.leftChild(T.root()) for a given tree T and position T.root(), it does not actually return to you an object of type BinaryTree; it returns to you a Position within the original tree T. You cannot send such a parameter recursively to search1.

For this reason, the book suggests defining a new recursive method with a different set of parameters (Code Fragment 9.1). In particular, we can define a new method as follows:

 // search for key k in the subtree of T rooted at position v

Position search1Recurse(int k, BinaryTree T, Position v) { if v is an external node then return null // search is unsuccessful if (k "matches" getKey(v)) then return v // success else if (k < getKey(v)) then return search1Recurse(k,T,T.leftChild(v)) else // must be that (k > getKey(v)) return search1Recurse(k,T,T.rightChild(v)) }

Using such a routine, you can implement the original method search1 by starting the recursion at the subtree rooted at position T.root().

Animation

We ask you to "animate" your routines by "marking" each node that you visit along the way. Our applet will highlight these marked nodes.

Files you will need

We will provide you with sourcecode for an applet which creates a valid binary search tree. You will need to download the source code we provide. The only file you will need to modify during the lab is Search.java.

WARNING: please heed the warning related to web browsers' caching of applet source code.

Handing in your completed lab

You do not have to submit any files electronically. You should instead make a printout of the modified file Search.java and make sure your name is written clearly at the top of the file.

Extra Credit - no points

If you have extra time, you might realize that the search procedure is so simple that there is really no need for recursion. It is possible to write code which accomplishes the search iteratively. In particular, one very carefully written loop can simulate a walk which starts at the root and proceeds down the tree until either the key is found or the bottom is reached.

You will notice a routine search2(int k, BinaryTree T) defined in the file Search.java. You will also find a button on the applet which invokes method search2. See if you can write code which accomplishes the search directly, without use of recursion.


Last modified: 7 November 2002