Binary Search Tree Remove method not working - java

public class BSTNode <E extends Comparable<E>> {
private E value;
private BSTNode<E> left;
public BSTNode<E> right;
....
public BSTNode<E>remove(E item) {
if(item.equals(this.value)){
return replacementSubtreeFromChildren(this.left, this.right);
}
if (item.compareTo(this.value)<0){
this.left = this.left.remove(item);
}
else{this.right = this.right.remove(item);
}
return this;
}
private BSTNode<E> replacementSubtreeFromChildren(BSTNode<E> left, BSTNode<E> right) {
if(left==null && right==null){
return null;
}
else if(left!=null && right==null){
return this.left;
}
else if(left==null && right!=null){
return this.right;
}
else{
E getleft=this.right.getLeftmostNode().getValue();
this.value = getleft;
this.right = right.remove(getleft);
}
return this;
}
/**
* Returns the leftmost node in the subtree formed by the receiver.
*
* COMPLETION
*
* HINT: The code is very simple. Just keep descending left branches,
* until it is no longer possible.
*
* #returns a reference to the leftmost node, starting from the receiver.
*
*/
private BSTNode<E> getLeftmostNode() {
if (this.left == null) {
return this;
}
else{
return this.left.getLeftmostNode();
}
For some reason this method will not remove from the tree.
Can anyone help me find why this it is doing this?
I have tested it and all the methods are being accessed, I suspect I have the pointer somewhere incorrectly however cannot find where.

inst this for comp103 Assignment 6 at Victoria university for this trimester

Related

Binary Search Tree implementation problem

I've got this BST I've built and trying to follow java code conventions I decided to fix around some of the access modifiers and add some getters and setters but now my entire code is giving me lots of problems in the execution and I cannot figure out why.
This is my Node class.
/**
* A class that implements a binary tree's node. It contains the data inside each node of the tree.
*/
public class Node {
private int data;
private Node left;
private Node right;
/**
* Constructor initializing the data of the node.
*
* #param data The numeric value of each node as an Integer.
*/
public Node(int data) {
this.data = data;
this.left = null;
this.right = null;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
This is the tree class.
import java.util.ArrayList;
import java.util.List;
/** Class implementation of a binary tree , containing helper classes and methods. */
public class BinaryTree {
private Node root;
private List<Integer> nodes = new ArrayList<>();
/** Constructor initializing the root node of the tree. */
public BinaryTree() {
root = null;
}
public Node getRoot() {
return root;
}
private Node insertNode(Node node, int dataBeingInserted) {
if (node == null) {
node = new Node(dataBeingInserted);
return node;
}
if (node.getData() > dataBeingInserted) {
insertNode(node.getLeft(), dataBeingInserted);
} else if (node.getData() < dataBeingInserted) {
insertNode(node.getRight(), dataBeingInserted);
}
return node;
}
/**
* Method that inserts nodes into the binary tree. If the tree is empty , a new root node is
* initialized.
*
* #param dataBeingInserted The number to be inserted as an integer.
*/
public void insertNode(int dataBeingInserted) {
root = insertNode(root, dataBeingInserted);
}
private Node searchTree(Node node, int dataBeingSearched) {
if (node == null || node.getData() == dataBeingSearched) {
return node;
}
if (node.getData() > dataBeingSearched) {
return searchTree(node.getLeft(), dataBeingSearched);
}
return searchTree(node.getRight(), dataBeingSearched);
}
/**
* Method that recursively searches for our element through the tree. If the value is present in
* the root node , or there aren't any nodes in the tree , the method returns the root node. If
* the value we're looking for is smaller than the root node's value , we search for our value in
* the left subtree , otherwise we search for it in the right subtree.
*
* #param dataBeingSearched User's value.
* #return Recursive call of the method.
*/
public Node searchTree(int dataBeingSearched) {
return searchTree(root, dataBeingSearched);
}
private String inorderTraversal(Node node) {
if (node == null) {
return "";
}
inorderTraversal(node.getLeft());
nodes.add(node.getData());
inorderTraversal(node.getRight());
return nodes.toString();
}
/**
* An implementation of the In-order traversal. First the left subtree is visited and printed
* accordingly, then we visit and print the root and after that we visit and print the right
* subtree.
*/
public String inorderTraversal() {
return inorderTraversal(root);
}
}
And those are some tests I wrote just to try some stuff.
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/** Binary tree operations tests. */
class BinaryTreeTests {
/** Testing whether the answer is correct if we search for the root value of the tree. */
#Test
void isSearchWorking() {
BinaryTree tree = new BinaryTree();
tree.insertNode(10);
tree.insertNode(30);
tree.insertNode(35);
tree.insertNode(29);
assertEquals(tree.getRoot(), tree.searchTree(20));
}
/** Testing whether the root changes it's value from null after a single insertion. */
#Test
void isInsertWorking() {
BinaryTree tree = new BinaryTree();
assertNotNull(tree.getRoot());
}
#Test
void inOrderTraversalPrint() {
BinaryTree tree = new BinaryTree();
tree.insertNode(10);
tree.insertNode(30);
tree.insertNode(35);
tree.insertNode(29);
assertEquals("[10, 20, 29, 30, 35]", tree.inorderTraversal());
}
#Test
void inOrderTraversalSameElement() {
BinaryTree tree = new BinaryTree();
tree.insertNode(1);
tree.insertNode(1);
tree.insertNode(1);
tree.insertNode(1);
tree.insertNode(1);
tree.insertNode(1);
assertEquals("[1]", tree.inorderTraversal());
}
}
So before I set the data , left and right variables in the Node class to public , everything was working just fine , now that they are private , only the last test passes for some reason.
isInsertWorking() is giving me expected not
inOrderTraversalPrint() is giving me just [10] instead of [10, 20, 29, 30, 35]
isSearchWorking() says expected node got null.
I currently do not know how to handle these things , I think my recursions might be incorrect but I cannot think of a way to fix them.
The main problem was in insertNode() function which I have fixed. There was a bug in searchTree() function and also I cleared the list nodes whenever inorderTraversal() is called since the tree can be modified between two inorderTraversal() calls.
import java.util.ArrayList;
import java.util.List;
/**
* A class that implements a binary tree's node. It contains the data inside each node of the tree.
*/
class Node {
private int data;
private Node left;
private Node right;
/**
* Constructor initializing the data of the node.
*
* #param data The numeric value of each node as an Integer.
*/
public Node(int data) {
this.data = data;
this.left = null;
this.right = null;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
/** Class implementation of a binary tree , containing helper classes and methods. */
class BinaryTree {
private Node root;
private List<Integer> nodes = new ArrayList<>();
/** Constructor initializing the root node of the tree. */
public BinaryTree() {
root = null;
}
public Node getRoot() {
return root;
}
private Node insertNode(Node node, int dataBeingInserted) {
if (node == null)
return new Node(dataBeingInserted);
if (node.getData() == dataBeingInserted)
return root;
if (node.getData() < dataBeingInserted) {
if (node.getRight() != null)
return insertNode(node.getRight(), dataBeingInserted);
else
node.setRight(new Node(dataBeingInserted));
} else if (node.getData() > dataBeingInserted) {
if (node.getLeft() != null)
return insertNode(node.getLeft(), dataBeingInserted);
else
node.setLeft(new Node(dataBeingInserted));
}
return root;
}
/**
* Method that inserts nodes into the binary tree. If the tree is empty , a new root node is
* initialized.
*
* #param dataBeingInserted The number to be inserted as an integer.
*/
public void insertNode(int dataBeingInserted) {
root = insertNode(root, dataBeingInserted);
}
private Node searchTree(Node node, int dataBeingSearched) {
if (node == null || node.getData() == dataBeingSearched) {
return node;
}
if (node.getData() > dataBeingSearched) {
return searchTree(node.getLeft(), dataBeingSearched);
} else {
return searchTree(node.getRight(), dataBeingSearched);
}
}
/**
* Method that recursively searches for our element through the tree. If the value is present in
* the root node , or there aren't any nodes in the tree , the method returns the root node. If
* the value we're looking for is smaller than the root node's value , we search for our value in
* the left subtree , otherwise we search for it in the right subtree.
*
* #param dataBeingSearched User's value.
* #return Recursive call of the method.
*/
public Node searchTree(int dataBeingSearched) {
return searchTree(root, dataBeingSearched);
}
private String inorderTraversal(Node node) {
if (node == null) {
return "";
}
inorderTraversal(node.getLeft());
nodes.add(node.getData());
inorderTraversal(node.getRight());
return nodes.toString();
}
/**
* An implementation of the In-order traversal. First the left subtree is visited and printed
* accordingly, then we visit and print the root and after that we visit and print the right
* subtree.
*/
public String inorderTraversal() {
nodes.clear(); // clear the previous state
return inorderTraversal(root);
}
}

Generic type safety warning

I'm getting the type safety warning everywhere in the program and I'm pretty sure I did something wrong the with the usage of generics. The warning is displayed in code mostly that has Node involved. Please point out the parts where my syntax is possibly not the most ideal and recommend changes to my code. Appreciate any help!
Removing the in Node class works!
public class BinaryTree<T extends Comparable<T>> {
private class Node<T>{
private T data;
private Node left;
private Node right;
// left and right child do not have to nessary exist
public Node ( T data) {
this.data = data;
this.left = null;
this.right = null;
}}
private Node<T>root;
private int count = 0;
public void add( T data) {
if ( isEmpty()) {
root = new Node(data);
count++;
}
else {
insert(data, root);
count++;
}
}
public boolean isEmpty() {
return root == null;
}
public T getRoot() {
if ( root.data == null) {
System.out.println("Root is empty");
return null;
}
else {
return root.data;
}}
/*
* Checking if the data is larger or lesser than the parent's data
* If the data is smaller than the parent's data, node.left is created
* If the data is bigger than the parent's data, node.right is created
*/
private void insert( T data, Node<T>node) {
/*
* If 1st obj is less than the 2nd obj return a neg
* if 1st obj is more than the 2nd obj return a pos
* if equal return 0
*/
int compare = data.compareTo(node.data);
if ( compare < 1 ){
if (node.left == null ) {
node.left = new Node(data);
}
// make node.left if it is filled
else {
insert(data, node.left);
}
}
else {
if ( node.right == null) {
node.right = new Node(data);
}
else {
insert( data, node.right);
}
}
}
public int getSize() {
return count;
}

What is wrong with my balance method in my BinarySearchTree? (Java)

I created a method that is suppose to balance a BinarySearchTree.
The instructions were that the balance method should update the tree so that it is balanced, meaning that the largest difference between subtree heights is no more than 1.
With the following process:
• Get an array of sorted values in the tree (we have a method that can do this)
• Assign the tree's root to the result of the buildTreeUtil helper method (described below)
• Call assignFirst to update the tree's "first" attribute
The buildTreeUtil(E[], int, int, BSTNode parent) helper method rebuilds the tree using a sorted list of values. Since it has this sorted list, it doesn't have to search for where to insert new values, so it doesn't (and shouldn't) call the add method. Instead, it selectively grabs values from the sorted list of values when adding new nodes. It's algorithm is as follows:
• If the "start" parameter is greater than the "end" parameter, the recursion should stop
• Create a new node storing the middle element in the list
• Assign the new node's left reference to a recursive call using the left half of the list
• Assign the new node's right reference to a recursive call using the right half of the list
Here is the following code:
public void balance()
{
this.root = buildTreeUtil(toArray(), 0, size(), first);
assignFirst();
}
private BSTNode<E> buildTreeUtil(E[] values, int start, int end, BSTNode<E> parent)
{
if(start > end)
{
return null;
}
int mid = (start + end)/2;
BSTNode<E> node = new BSTNode<E>(values[mid]);
node.left = buildTreeUtil(values, start, mid - 1, parent.left);
node.right = buildTreeUtil(values, mid + 1, end, parent.right);
return node;
}
private void assignFirst()
{
if (root.left != null)
{
first.left = first;
}
else
{
first = root;
}
}
#SuppressWarnings("unchecked")
public E[] toArray()
{
ArrayList<E> aList = new ArrayList<E>();
E[] arr = (E[]) new Comparable[this.numElements];
toArray(this.root, aList);
return aList.toArray(arr);
}
private void toArray(BSTNode<E> node, List<E> aList)
{
if (node != null)
{
toArray(node.left, aList);
aList.add(node.data);
toArray(node.right, aList);
}
}
This is just the rest of my code cut short so there is some valuable background information.
public class BinarySearchTree<E extends Comparable<E>>
{
private BSTNode<E> root; // root of overall tree
private int numElements;
private BSTNode<E> first;
// post: constructs an empty search tree
public BinarySearchTree()
{
this.root = null;
this.numElements = 0;
}
public class Iterator
{
private BSTNode<E> currentNode;
public Iterator()
{
currentNode = first;
}
public boolean hasNext()
{
return currentNode != null;
}
public E next()
{
E value = currentNode.data;
currentNode = currentNode.next;
return value;
}
}
private static class BSTNode<E>
{
public E data;
public BSTNode<E> left;
public BSTNode<E> right;
public BSTNode<E> parent;
public BSTNode<E> next;
public BSTNode(E data)
{
this(data, null, null, null, null);
}
public BSTNode(E data, BSTNode<E> left, BSTNode<E> right, BSTNode<E> parent, BSTNode<E> next)
{
this.data = data;
this.left = left;
this.right = right;
this.parent = parent;
this.next = next;
}
}
}
I'm not sure where the error occurs or if I'm assigning the incorrect values inside the parameters for buildTreeUtil.

Binary tree merge?

I am new to stack over flow so sorry for any mistakes, but i am trying to answer this question :
"Write a method that takes two binary trees t1, t2 and a binary tree node v as the arguments. It constructs and returns a new binary tree that has v as its root and whose left subtree is t1 and whose right subtree is t2."
I have done hours of attempts and cant seem to even make 1 binary tree.. The teacher wont really explain and wants us to do it using objects. This is the format she wants us to use.. Can someone please help me..
the commented out stuff is just my attempts to get something to work..
public class treeNode
{
private Object da;
private treeNode left;
private treeNode right;
public treeNode(Object newItem)
{
da = newItem;
left = null;
right = null;
}
public treeNode(Object newItem, treeNode leftNode, treeNode rightNode)
{
da = newItem;
left = leftNode;
right = rightNode;
}
public void setItem(Object newItem)
{
da = newItem;
}
public Object getItem()
{
return da;
}
public void setLeft(treeNode leftNode)
{
left = leftNode;
}
public treeNode getLeft()
{
return left;
}
public void setRight(treeNode rightNode)
{
right = rightNode;
}
public treeNode getRight()
{
return right;
}
//------------------------
public void buildTree()
{
}
//public void combine (l , r)
//{
// T = 5;
// setLeft(l);
// setRight(r);
// return T;
//}
//-----------------------
public static void main (String args [])
{
// treeNode a = new treeNode(5);
// treeNode b = new treeNode(8);
// treeNode c = new treeNode(2);
// a.setLeft(b);
// a.setRight(c);
// System.out.println(a.da);
// System.out.println(a.getLeft() );
// System.out.println(a.getRight() );
// treeNode t = new treeNode();
// t.left = t1;
// t.right = t2;
// System.out.println(buildTree(t));
}
}
My solution consists of two classes: Tree and Node.
The solution can be implemented with just Node, but since you were asked that the function will receive a two trees and a node so I implemented it like this. I don't know if you know java generics(The 'T' I used), if you don't, you can use Object like the code you posted. I'm ignoring all the getters and setters, but of course you can add them.
Node class:
public class Node<T> {
private T data;
private Node right;
private Node left;
public Node(T data) {
this.data = data;
}
public Node(T data, Node right, Node left) {
this.data = data;
this.right = right;
this.left = left;
}
}
Tree class:
public class Tree<T> {
private Node<T> root;
public Tree(Node root) {
this.root = root;
}
public Node<T> getRoot() {
return root;
}
}
The combine function:
public Tree combine(Tree t1, Tree t2, Node v) {
return new Tree(new Node(v, t1.getRoot(), t2.getRoot()));
}

Level traversal in binary tree

Here is the part of code of the binary tree class that I'm writing.
class Node<T> {
private T value;
private Node<T> left;
private Node<T> right;
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getLeft() {
return left;
}
public void setLeft(Node<T> left) {
this.left = left;
}
public Node<T> getRight() {
return right;
}
public void setRight(Node<T> right) {
this.right = right;
}
public Node() {}
public Node(T value) {
this.value = value;
}
public Node(T value, Node<T> left, Node<T> right) {
this.value = value;
this.left = left;
this.right = right;
}
}
import java.util.*;
public class Tree<T extends Comparable<T>> {
private Node<T> root;
private List<T> levelOrderList = new ArrayList<T>();
public Node<T> getRoot() {
return root;
}
public Tree() {
}
public Tree(Node<T> root) {
this.root = root;
}
private List<T> getLevelOrderList(Node<T> root){
if (root == null)
return Collections.emptyList();
Queue<Node<T>> level = new LinkedList<Node<T>>();
level.add(root);
while(!level.isEmpty()){
Node<T> node = level.poll();
levelOrderList.add(node.getValue());
if(node.getLeft() != null)
level.add(node.getLeft());
if(node.getRight() != null)
level.add(node.getRight());
}
return levelOrderList;
}
public List<T> getLevelOrderList() {
return getLevelOrderList(root);
}
}
The method getLevelOrderList() returns list of elements in tree in level by level order.
The question is: how to rewrite method getLevelOrderList using recursion?
What you need to do is remove the loop, and just focus on a single pass through what now is in the loop. You'll need to move some of that code out of the private method and into the public method you created. Like the check for root == null, level instantiation, etc. Then you'll just keep calling the private method until level is empty. Here is how I'd change the signature:
public List<T> getLevelOrderList() {
if( root == null ) return Collections.emptyCollection();
List<Node<T>> level = new ArrayList<Node<T>>();
List<T> values = new ArrayList<T>();
level.add( root );
return getLevelOrderList( level, values );
}
private List<T> getLevelOrderList(List<Node<T>> level, List<T> values) {
if( level.isEmpty() ) return values;
// do the next step to visit the node at the head of the list and recurse
}
That should be enough to get you started, but I can't give this away since it's clearly homework. Oh and your program had a bug if you called getLevelOrderList() twice it would never clear out the instance variable you had so it would return double the number of items from the tree. By not using instance variables I removed that bug.

Categories

Resources