void preorder(Consumer<E> consumer)
Performs preorder traversal of this tree (see next method).
See section Consumer Interface below and copy the given code for StringConsumer in its own file in the project.
Initially, could ignore the consumer and write the code as if the intent is to print the items during the traversal. Then, instead of giving the items to the "printer", give them to the consumer .
JUnit: This will require 5 lines. Create StringConsumer and check that the string value accumulated by the consumer matches the expected result (i.e. the items are listed in preorder sequence):
tree = load( ... );
consumer = create StringConsumer object;
tree.preorder( consumer );
assertEquals( consumer's value, "[...the items listed in preorder...]" );
assertEquals( tree.toString(), "[...the items listed in level order...]" );
The second line is needed before each traversal to ensure that the consumer is reset/blank before the traversal. You could declare the consumer object at the top (as a data member like the tree ).
|
void preorder(Consumer<E> consumer, Node curr)
Performs preorder traversal of the tree rooted at the given node curr .
Nothing is printed here. Instead the items are given to the consumer .
|
void inorder(Consumer<E> consumer)
Performs inorder traversal of this tree (see next method). See method preorder for how to test.
|
void inorder(Consumer<E> consumer, Node curr)
Performs inorder traversal of the tree rooted at the given node curr .
|
void postorder(Consumer<E> consumer)
Performs postorder traversal of this tree (see next method). See method preorder for how to test.
|
void postorder(Consumer<E> consumer, Node curr)
Performs postorder traversal of the tree rooted at the given node curr .
|
boolean equals(Object other)
Returns true if the given object is equal to this tree (see next method; see also DLinkedList class)
Here is an example of the typical steps in implementing method equals(...) ; note that a typecast is required to convert from Object to the specific class:
Cat.java
JUnit: Compare the trees with themselves, with each other, and with things that are not trees. Note, that these tests are not likely to be sufficient.
|
boolean equals(Node root1, Node root2)
(recursive) Returns true if the trees rooted at the given nodes are identical, i.e. have identical items and identical structure.
|
Object clone()
Returns a copy of this tree (your class must implement the Cloneable interface).
The code for this method is given. It relies on the next method:
public Object clone()
{
try {
BSTree<E> copy = (BSTree<E>) super.clone();
copy.comp = this.comp;
copy.root = copyTree(this.root);
return copy;
}
catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
|
Node copyTree(Node curr)
(recursive) Returns a copy of the tree rooted at the given node (the two trees should be independent -- adding to or removing from one, should not affect the other).
|
BSTree(Comparator<E> comp, E... items)
Creates the tree from the given array of items (see below for the
E... notation). It is assumed that the items in the array are arranged in preorder sequence.
The code for this constructor is given. It relies on the next method:
BSTree(Comparator<E> comp, E... items)
{
this.comp = comp;
this.root = rebuildPreorder(items, 0, items.length - 1);
}
The notation E... is roughly equivalent to declaring a primitive array from CS111, but it allows for a nicer way of calling the constructor (see method load in BSTreeTest ).
JUnit: Instead of method load use the new constructor to build the tree:
tree = new BSTree<¿>( theComp, u, v, w x, y );
Assert that toString() produces the expected result. (only 2 lines)
|
Node rebuildPreorder(E[] items, int i, int j)
(recursive) Creates a tree from the given preorder array of items contained between indices [i,j] (the range is inclusive, i.e. contains all items that are in the corresponding tree).
Hint: Traverse the items to find index m that separates the range [i,j] into two sections [?,?] and [?,?] .
|
String toString()
Returns a string representation of the tree listing the elements in level-order sequence in the format [a b c d].
The goal is to replace the version based on BSTreeUtils with your own version that uses the level-order iterator to collect all items in the tree and build the string. The two versions should produce identical output.
This method will test implicitly the level-order iterator in the JUnit tester.
All test cases (from Assignments 5 and 6) should still work without modification, since the new toString() should give the same output as the helper from BSTreeUtils .
|
Iterator<E> iterator()
Returns an iterator over this tree that enumerates the elements in level-order sequence (method remove() is not supported).
The Level-Order Iterator keeps a Queue of waiting nodes and gives values one at a time, possibly adding on to the waiting nodes.
What will be the order if the Queue is replaced with a Stack ?
|
@Test
void test_iterFails()
Add this method in the Tester class. For each type of tree (empty, single, multi) it tests the iterator of that tree for all possible failing conditions of the method next() , i.e. the conditions under which these methods throw exceptions.
The goal is to have each line in the Iterator class marked green.
Here is the structure of the tests: one group per list, for a total of 3 groups, each group is longer than 4 lines:
tree = load( m,y,n,u,m,b,e,r,s);
Iterator<???> iter = tree.iterator();
 // rule-of-3 does not apply, ok (necessary) to have multiples of this line here:
 iter.next(), ... [sometimes in assertThrows]
assert toSting for the tree
|
CountRangeConsumer
See the Consumer interface and the examples below and create a new generic class, CountRangeConsumer , which counts the number of items in the tree that are in the given range [a,b] (inclusive):
Create class CountRangeConsumer in its own file in the project. Here is a starting point:
CountRangeConsumer.java
The constructor of the CountRangeConsumer takes the values of the desired range [a,b] and the comparator that was used to create the tree. These will be used to decide whether the accepted item is inside the range. Note that the type of the range [a,b] is not Integer .
JUnit: Test in method test_CountRangeConsumer by creating CountRangeConsumer objects:
tree = load( ... );
consumer = create CountRangeConsumer object with some range and comparator;
tree.preorder( consumer );
assertEquals( consumer's value, ...the expected value...]" );
assertEquals( tree.toString(), "[...the items listed in level order...]" );
*** try different trees and different interesting ranges ***
There should be only one class called CountRangeConsumer -- no other subclasses or similar classes should be created. The effect of having different CountRangeConsumer s is achieved by creating several objects of the class CountRangeConsumer by specifying the item type and supplying the correct comparator (the one that built the tree).
|