Gettysburg College

CS 216
Data Structures

Spring 2024

Assignment 5

Due: Mon, Mar 4, by 11:59pm
  • method stubs: BSTree.java
  • junit tests: BSTreeTest.java
    • tester method test_addLoop confirms working constructor, addLoop, toString
    • read sections JUnit Tests and BSTreeUtils
  • coverage.pdf
  • api.pdf
Due: Thu, Mar 7, by 11:59pm
  • BSTree.java
  • BSTreeTest.java
  • coverage.pdf

Description

Implement the Binary Search Tree data structure which supports the methods given below.

Create a project named BSTree with class BSTree that has:

Note the following about the methods:

The Comparator

In Java generic types cannot be compared using <, >, etc. 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:

either 3 lines or 4 lines, 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 add(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).
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 [a b c d e f] 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 );
}
                a
             /     \
  the tree: b       c
             \     / \
              d   e   f
                   \
                    g

the string: [a b c d e f g]

BSTreeUtils

Download the bstreevis.jar file in the BSTree project folder (next to folders bin/ src/:

To be able to use the .jar package, make sure that:

Tree Visualizer (Optional)

This is optional: The bstreevis.jar package has an application (courtesy Dr. Kim) that helps visualize a binary search tree.

Create class BSTreeVisualize in your project and copy the following code:

BSTreeVisualize.java

This is not the same as the unit tests file BSTreeTest. Running this will show a sequence of images with the current state of the tree.