I have written a code of Binary Search tree that extends comparable and implements an interface. The code for leaves and the helper method countLeaves, makes sure that all of the test goes through except for one, heightIsLogOfNumLeavesTreeIsPerfect().
// TODO: Look at the Leaves and helper method in the tree class and see how I should change it so that this test goes through aswell.
//EDIT: Added the whole testclass
I have also included the message i get when the test does not go through and the test in the test class
java.lang.AssertionError:
Expected: <2>
but: was <0>
Expected :<2>
Actual :<0>
import org.junit.Test;
import org.junit.Before;
import org.junit.Rule;
import org.junit.rules.Timeout;
import static org.junit.Assert.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.*;
import java.util.Arrays;
import java.util.stream.IntStream;
/**
* Test class for a tree.
*
* @author Melissa Saber Tehrani
* @version 2022-02-12
*/
public class TreeTest{
@Rule public Timeout globalTimeout = Timeout.seconds(5);
Tree<Integer> tree;
int[] elementsInTree;
int[] elementsNotInTree;
@Before
public void setUp() {
/**
* This tree should look like this:
*
* 8
* / \
* 3 10
* / \ \
* 1 6 14
* / \ /
* 4 7 13
*/
tree = new Tree<>();
elementsInTree = new int[] {8, 10, 14, 13, 3, 1, 6, 4, 7};
for (int elem : elementsInTree) {
tree.insert(elem);
}
elementsNotInTree = new int[] {34, -3, -10, 12, 74, 5};
}
// Tests for height
@Test
public void heightIsZeroWhenTreeIsEmpty() {
// Arrange
Tree<Integer> emptyTree = new Tree<>();
// Act
int height = emptyTree.height();
// Assert
assertThat(height, equalTo(0));
}
@Test
public void heightIsZeroWhenTreeHasOnlyRoot() {
// Arrange
Tree<Integer> rootOnlyTree = new Tree<>();
rootOnlyTree.insert(1338);
// Act
int height = rootOnlyTree.height();
// Assert
assertThat(height, equalTo(0));
}
@Test
public void heightIsLogOfNumLeavesTreeIsPerfect() {
// For a perfect tree, tree.height() == log2(tree.leaves()
// Arrange
Tree<Integer> tree = new Tree<>();
int[] elements = new int[] {8, 3, 10, 1, 6, 9, 14};
int numLeaves = 4;
int logNumLeaves = (int) Math.round(Math.log(numLeaves) / Math.log(2));
for (int elem : elements) {
tree.insert(elem);
}
// Act
int height = tree.height();
// Assert
assertThat(height, equalTo(logNumLeaves));
}
}
/**
* An interface describing a generic Comparable
*/
public interface BSTInterface <T>{
boolean search(T elem);
boolean insert(T elem);
int size();
int height();
int leaves();
}
/**
* An Binary Search tree implementation of the comparable interface.
* @param <T>
*/
public class Tree <T extends Comparable <T>> implements BSTInterface <T>{
private int size;
private Node root;
public class Node{
private Node Left;
private Node Right;
private T data;
public Node(T data){
this.data = data;
}
public Node getRight(){
return Right;
}
public Node getLeft() {
return Left;
}
public T getData() {
return data;
}
}
public Tree (){
size = 0;
root = null;
}
/**
* Test for presence of a value.
* @param elem
* @return true/false
*/
@Override
public boolean search(T elem) {
if(root == null ||elem == null){
return false;
}
Node node = root;
while(true){
if(node.data.compareTo(elem) > 0){
if(node.Right == null){
return false;
} else{
node = node.Right;
}
} else if(node.data.compareTo(elem) == 0){
break;
} else{
if(node.Left== null){
return false;
}
else{
node = node.Left;
}
}
}
return true;
}
/**
* Add value to tree; duplicates are not allowed.
* Return true if the element is not already present (and is thus inserted),
* false otherwise.
*
* @param elem
* @return true/false
*/
@Override
public boolean insert(T elem) {
if (elem == null){
return false;
}
if (root == null){
root = new Node(elem);
size++;
return true;
}
Node node = root;
while (true){
if (node.data.compareTo(elem) > 0) {
if (node.Right == null){
node.Right = new Node(elem);
size++;
break;
} else {
node = node.Right;
}
} else if (node.data.compareTo(elem) == 0) {
return false;
} else {
if (node.Left == null){
node.Left = new Node(elem);
size++;
break;
} else {
node = node.Left;
}
}
}
return true;
}
/**
* the number of elements in the tree
* @return size.
*/
@Override
public int size() {
return size;
}
/**
* The height of the tree.
* The empty tree and the tree with only the root node both have height 0.
* @return the height of the tree.
*/
@Override
public int height() {
return countHeight(root);
}
/**
* Helper method for height
*/
private int countHeight(Node node){
if(node == null) {
return 0;
}
int rightHeight = countHeight(node.Right);
int leftHeight = countHeight(node.Left);;
int height = Math.max(leftHeight, rightHeight);
return height;
}
/**
* The number of leaves in the tree.
* @return the amount of leaves the tree have.
*/
@Override
public int leaves() {
return countLeaves(root);
}
/**
* Helper method for leaves
*/
private int countLeaves(Node node) {
if (node == null) {
return 0;
}
if (node.Right == null && node.Left == null) {
return 1;
}
int count = 0;
count += countLeaves(node.Left);
count += countLeaves(node.Right);
return count;
}
/**
* A string describing the tree
* @return
*/
public String toString(){
String str = "[" + helpToString(root);
if (str.length() > 1) {
str = str.substring(0, str.length() - 2);
} return str + "]";
}
/**
* Helper method for toString
*/
private String helpToString(Node node) {
String str = "";
if (node != null) {
str += helpToString(node.Right);
str += node.data + ", ";
str += helpToString(node.Left);
}
return str;
}
}
D. Now, is the height of a BST: (1) the number of edges on a path from the root node toD, or (2) is it the number of nodes on a path from the root node toD? \$\endgroup\$