Description
Implement the
Binary Search Tree data structure which supports the methods given below.
Create a project named BSTree
with class BSTree
that has:
- non-private inner class
Node
with members for data item, left child, right child, and parent
- data member that points to the
root
of the tree (similar to the pointer to the head
in a LinkedList
, but there is no dummy here)
- data member of type
Comparator<E>
that will be used to compare the items in the nodes (see below)
Note the following about the methods:
- Some methods use recursion and some use loop. The versions that use loop have the suffix
Loop
in the method name.
- Methods that return
Node
or take Node
as parameters are private
. They are tested implicitly by testing the public methods. For example, contains
implicitly tests findNode
. This means that the private methods are not tested in JUnit directly.
- Methods should not throw exceptions, unless there is no other way to communicate failure. For this assignment, only
NoSuchElementException
is relevant (if exception is needed).
The Comparator
In Java generic types cannot be compared using
< >
. Instead, we are going to use the
Comparator Interface.
Create class
IntComparator
in your project and copy the following code:
IntComparator.java
Inside the
BSTree
you would write:
if ( your-comp.compare(xxx, yyy) < 0 ) instead of if ( xxx < yyy )
if ( your-comp.compare(xxx, yyy) > 0 ) instead of if ( xxx > yyy )
if ( your-comp.compare(xxx, yyy) == 0 ) instead of if ( xxx == yyy )
where
your-comp
is your
Comparator
data member (see above).
JUnit Tests
Copy to your Tester the contents of the following file and make the relevant updates/changes:
BSTreeTest.java
The expectations for testing are identical to those in Assignment 2:
but use 3 lines per test since there is only one toString
method
Here there is still the concept of
first(the min) | middle(inside) | last(the max)
, but there are typically more things to try, since for every
Left there is a Right, and for every
Right there is a Left.
Test cases can be reused. For example,
containsLoop
and
contains
do the same thing, so they can use the same test cases.
The private methods (those that return
Node
or take
Node
as parameters) will be tested implicitly by the corresponding public methods, so do not write test cases for the private methods. For example,
contains
implicitly tests
findNode
.
Required API
Implement the following methods for the
Binary Search Tree data structure:
BSTree(Comparator<E> theComp)
Creates an empty tree that uses the given comparator to compare the values in the tree (see section The Comparator).
There is no dummy node here, so this is similar to the singly-linked list from class. Make sure to mention all data members.
|
void addLoop(E item)
Adds the given item to the tree.
Initially you may use the given helper method. Eventually replace with the actual code.
Follow the steps outlined in section BSTreeUtils in order to be able to use the helper utilities.
public void addLoop(E item)
{
your-root = new BSTreeUtils<E>().add( your-root, your-comp, new Node(item) ); // helper version
}
|
boolean isEmpty()
Determines if the tree is empty.
|
Methods That Use Loop
|
E maxValueLoop()
Returns the largest value in the tree (see findMaxNodeLoop ).
|
Node findMaxNodeLoop(Node node)
Returns the node with the largest value in the sub-tree rooted at the given node node.
|
boolean containsLoop(E item)
Determines if the tree contains the given item (see findNodeLoop ).
|
Node findNodeLoop(Node node, E item)
Finds the node in the sub-tree rooted at the given node node that contains the given item .
|
Methods That Use Recursion
recursive example at end of SLinkedList.java
see toString() and toString(Node curr)
|
void add(E item)
Adds the given item to the tree (see next method).
Initially you may use the given helper method. Eventually replace with the actual code.
Follow the steps outlined in section BSTreeUtils in order to be able to use the helper utilities.
public void add(E item)
{
your-root = new BSTreeUtils<E>().add( your-root, your-comp, new Node(item) ); // helper version
}
|
void add(Node curr, E item)
Recursive version of addLoop . Adds the given item to the sub-tree rooted at the given curr node.
|
E maxValue()
Returns the largest value in the tree (see findMaxNode ).
|
Node findMaxNode(Node curr)
Recursive version of findMaxNodeLoop .
|
boolean contains(E item)
Determines if the tree contains the given item (see findNode ).
|
Node findNode(Node curr, E item)
Recursive version of findNodeLoop .
|
Remove Methods: No Loops, No Recursion
|
boolean remove(E item)
Removes the given item from the tree.
|
void removeMissing(Node node)
Removes the given node assuming it is missing one or both children.
The node is detached from the tree by connecting the node's parent to the node's only child.
|
void removeHasBoth(Node node)
Removes the given node assuming it has exactly two children.
The node is not detached from the tree. Instead, the node value is replaced by the max value in the sub-tree on the left side of the node , and then the node with the max value is detached/removed from the tree (note: the max value node must be missing a child).
|
toString
|
String toString()
Returns a string representation of this tree ( level-by-level, left-to-right as illustrated below):
[] for empty tree and [e d c a b f g] for non-empty tree
This method is given (you do not have to write it). Follow the steps outlined in section BSTreeUtils in order to be able to use the helper utilities.
public String toString()
{
return new BSTreeUtils<E>().toString( your-root );
}
|
e
/ \
the tree: d c
\ / \
a b f
\
g
the string: [e d c a b f g]
|
|
BSTreeUtils
Download the
bstreevis.jar
file in the
BSTree
project folder (next to folders
bin/ src/
):
- bstreevis.jar (right-click, Save As...)
- add the .jar file as External Archive to the Build Path of your project: click here
To be able to use the
.jar package, make sure that:
- class
BSTree
has non-private internal class named Node
- class
Node
has non-private date members with these names:
data, left, right, parent