I'm really struggling with this. I can't figure out why I can't compare the value with Node.value...
line:
if (value < currentNode.value) {
problem: Operator '<' cannot be applied to 'V','java.lang.Comparable'
public class BinaryTree<V extends Comparable<V>> {
Node<V> root;
public void addNode(V value) {
Node newNode = new Node(value);
if (root == null) {
root = newNode;
} else {
Node<V> currentNode = root;
Node<V> parent;
while (true) {
parent = currentNode;
if (value.compareTo(currentNode.value) == -1) {
currentNode = currentNode.left;
if (currentNode == null) {
parent.left = newNode;
return;
}
} else {
currentNode = currentNode.right;
if (currentNode == null) {
parent.right = newNode;
return;
}
}
}
}
}
public int compareTo(V v){
if(this.V > v) return 1;
if(this.V < v) return -1;
else return 0;
}
}
Your node should also have a generic type which extends comparable Node<V extends Comparable<V>> and should be initialized with that generic Node<V> root - this applies to all Node variables.
Related
I am supposed to implement a recursive linked list, but after writing the code and debugging, it seems that my front node is remaining unchanged (it is staying at null). Any help will be appreciated.
public class RecursiveLinkedCollection<T> implements CollectionInterface<T> {
LLNode<T> front;
int size = 0;
RecursiveLinkedCollection() {
front = null;
size = 0;
}
private LLNode<T> recAdd(LLNode<T> node, T data) {
if(node == null) {
LLNode<T> newNode = new LLNode<T>(data);
node = newNode;
}
if(node.getLink() == null) {
LLNode<T> newNode = new LLNode<T>(data);
node.setLink(newNode);
return newNode;
}
return recAdd(node.getLink(), data);
}
#Override
public boolean add(T data) {
recAdd(front, data);
return true;
}
}
According to your add method, you try to append the new node from the front-node. In your recursion if you check for node being null, this can only happen if front is not set. You try to set node = newNode, but because java is always pass-by-value the reference to front is never set.
public class RecursiveLinkedCollection<T> implements CollectionInterface<T> {
LLNode<T> head;
int size;
RecursiveLinkedCollection() {
}
private LLNode<T> recToTail(LLNode<T> next, T data) {
LLNode<T> newNode = new LLNode<T>(data);
if(next == null) {
head = newNode;
size++;
return head;
}
if(next.getLink() == null) {
next.setLink(newNode);
size++;
return newNode;
}
return recAdd(next.getLink(), data);
}
#Override
public boolean add(T data) {
return recAdd(head, data) != null;
}
}
My removal method consists of 4 if statements that tackle the 4 different kinds of removal in a binary search tree. Not sure where wrong but it didn't remove any node when I check it. Any help if appreciated. Thanks in advance'
I suspect the problems lies in are where I try to replace the node removal to be null
public class BinaryTree<T extends Comparable<T>> {
private class Node{
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 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;
}}
public Node getRootNode() {
return root;
}
/*
* 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 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;
}
public boolean search ( T data) {
Node temp = searchInner(data, root);
if ( temp.data == data) {
System.out.println(temp.data);
return true;
}
else {
return false;
}
}
public Node searchInner( T data, Node node) {
int compare = data.compareTo(node.data);
if ( getRoot() == data ) {
return root;
}
if ( compare > 0) {
return searchInner( data, node.right);
}
if ( compare < 0 ) {
return searchInner(data , node.left);
}
if ( compare == 0 ) {
return node;
}
else {
System.out.println("Not found");
return node;
}
}
public void remove( T data) {
remove1( root, data);
}
private Node remove1( Node node1, T data) {
Node parent = root;
Node node = root;
Node temp;
boolean isLeft = true;
while ( node.data != data) {
parent = node;
if ( isEmpty()) {
System.out.println("Unable to remove, root is empty");
break;
}
if ( compare(data, node.data) < 0) {
node = node.left;
isLeft = true;
}
if ( compare(data, node.data) > 0) {
node = node.right;
isLeft = false;
}
else {
// remove node if left child available
if ( node.left == null && node.right != null) {
if ( isLeft) {
parent.left = node.right;
}
else {
parent.right = node.right;
}
count --;
break;
}
//remove node if right child available
if ( node.right == null && node.left != null) {
if ( isLeft) {
parent.left = node.left;
}
else {
parent.right = node.left;
}
count --;
break;
}
// Remove node if 2 child available
if ( node.left != null && node.right != null ) {
node = min(node.right);
node.right = remove1(node.right, node.data);
}
// remove node if no child available
if ( node.left == null && node.right == null) {
if ( isLeft ) {
parent.left = null;
}
else {
parent.right = null;
}
count --;
break;
}
}
}
return node;
}
// fine the smallest node in the right subtree
private Node min ( Node node1 ) {
while ( node1.left != null) {
node1 = node1.left;
}
return node1;
}
private int compare( T data, T data1) {
return data.compareTo(data1);
}
public void printBST(T data) {
printTree( root, data);
}
private void printTree( Node node, T data)
{
if(node == null) return;
System.out.println(data + " + " + node.data);
printTree(node.left , data);
printTree(node.right , data);
}
public int getHeight() {
return height(root);
}
private int height( Node node) {
if (node == null) return 0;
else
return 1 + Math.max(height(node.left), height(node.right));
}
public void print() {
println(root);
}
private void println ( Node node) {
LinkedList<T> q = new LinkedList<T>();
q.add(node.data);
if ( node == null) {
return;
}
int size = getSize();
while ( size > 0) {
System.out.print(q);
q.clear();
if ( node.left != null) {
q.add(node.left.data);
size --;
}
if ( node.right != null) {
q.add(node.right.data);
size --;
}
if ( node.right != null&& node.left != null) {
System.out.println();
}
if ( size > 1) {
System.out.println(",");
}
}
}
public boolean sameTree( Node root1, Node root2) {
if ( root1 == null && root2 == null) {
return true;
}
if ( root1 != null && root2 != null) {
return root1.data == root2.data && sameTree(root1.left,root2.left) && sameTree(root1.right, root2.right);
}
else {
return false;
}
}
}
I have rewritten your BinaryTree class. I have added a new remove method, which uses your min(Node node) method and other one I have created, that only removes the minimum element of the tree. In addition, I have modified your Node class too by adding a new constructor and added your size variable that was in BinaryTree class
I have modified all of this in order to make the method remove() working properly
import java.util.LinkedList;
public class BinaryTree<T extends Comparable<T>> {
private class Node<T> { //Here we specify what the node contains
private T data;
private Node<T> left;
private Node<T> right;
private int size;
public Node(T value) {
this(value, null, null);
}
// left and right child do not have to nessary exist
public Node(T data, Node<T> left, Node<T> right) {
this.data = data;
this.left = null;
this.right = null;
size = 1;
if (left != null) {
size += left.size;
}
if (right != null) {
size += right.size;
}
}
}
private Node root;
public BinaryTree() { //Added a constructor to set the root node to null
root = null;
}
public boolean isEmpty() {
return root == null;
}
public T getRootData() { //Changed the name to other more clear
if (root.data == null) {
System.out.println("Root is empty");
return null;
} else {
return (T) root.data;
}
}
public Node getRootNode() {
return root;
}
public void insert(T x) { //The new insert method
root = insert(x, root);
}
protected Node<T> insert(T x, Node<T> actual) {
//We check if the node exists, in case not we just create a new node
if (actual == null) {
return new Node<T>(x);
}
int cmp = compare(x, actual.data);
if (cmp < 0) {
actual.left = insert(x, actual.left);
} else if (cmp > 0) {
actual.right = insert(x, actual.right);
} else {
// If the node exists we just update his content
actual.data = x;
}
actual.size = 1 + getSize(actual.left) + getSize(actual.right);
return actual;
}
public int getSize() { //New method
return getSize(root);
}
private int getSize(Node<T> actual) {
if (actual == null) {
return 0;
} else {
return actual.size;
}
}
public boolean search(T data) {
Node temp = searchInner(data, root);
if (temp.data == data) {
System.out.println(temp.data);
return true;
} else {
return false;
}
}
public Node searchInner(T data, Node node) {
int compare = data.compareTo((T) node.data);
if (getRootData() == data) {
return root;
}
if (compare > 0) {
return searchInner(data, node.right);
}
if (compare < 0) {
return searchInner(data, node.left);
}
if (compare == 0) {
return node;
} else {
System.out.println("Not found");
return node;
}
}
public void remove(T data) {
remove1(root, data);
}
private Node remove1(Node actual, T data) {
if (actual == null) {
return actual;
}
int cmp = compare(data, (T) actual.data);
//Check whether the value is lesser greater or equal than the one we are just visiting
if (cmp < 0) {
actual.left = remove1(actual.left, data);
} else if (cmp > 0) {
actual.right = remove1(actual.right, data);
} else {
if (actual.right == null) {
return actual.left;
}
if (actual.left == null) {
return actual.right;
}
actual.data = min(actual.right).data;
actual.right = removeMin(actual.right);
}
return actual;
}
public Node removeMin() {
//A new method to remove the minimum element
Node min = min(root);
root = removeMin(root);
return min;
}
private Node removeMin(Node actual) {
if (actual.left == null) {
return actual.right;
}
actual.left = removeMin(actual.left);
actual.size--;
return actual;
}
// fine the smallest node in the right subtree
private Node min(Node node1) {
while (node1.left != null) {
node1 = node1.left;
}
return node1;
}
private int compare(T data, T data1) {
return data.compareTo(data1);
}
public void printBST(T data) {
printTree(root, data);
}
private void printTree(Node node, T data) {
if (node == null) {
return;
}
System.out.println(data + " + " + node.data);
printTree(node.left, data);
printTree(node.right, data);
}
public int getHeight() {
return height(root);
}
private int height(Node node) {
if (node == null) {
return 0;
} else {
return 1 + Math.max(height(node.left), height(node.right));
}
}
public void print() {
println(root);
}
private void println(Node node) {
LinkedList<T> q = new LinkedList<T>();
q.add((T) node.data);
if (node == null) {
return;
}
int size = getSize();
while (size > 0) {
System.out.print(q);
q.clear();
if (node.left != null) {
q.add((T) node.left.data);
size--;
}
if (node.right != null) {
q.add((T) node.right.data);
size--;
}
if (node.right != null && node.left != null) {
System.out.println();
}
if (size > 1) {
System.out.println(",");
}
}
}
public boolean sameTree(Node root1, Node root2) {
if (root1 == null && root2 == null) {
return true;
}
if (root1 != null && root2 != null) {
return root1.data == root2.data && sameTree(root1.left, root2.left) && sameTree(root1.right, root2.right);
} else {
return false;
}
}
}
I hope this helps to you
everyone.
I am trying to come up with a way to allow the user to create a tree at run-time, with a branching factor of 2 and an unlimited depth (depends on user).
The user must begin with the root_node, then go on to the root node's two children (left_node and right_node). after that the left child becomes the root and the user does the same process and moves on to the right child.
Any help on how to achieve this is appreciated.
Thanks in advance
Are you looking for something like this?
import java.util.LinkedList;
import java.util.Queue;
public class BinaryTree {
Node root;
public void add(int value) {
root = addRecursive(root, value);
}
private Node addRecursive(Node current, int value) {
if (current == null) {
return new Node(value);
}
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
}
return current;
}
public boolean isEmpty() {
return root == null;
}
public int getSize() {
return getSizeRecursive(root);
}
private int getSizeRecursive(Node current) {
return current == null ? 0 : getSizeRecursive(current.left) + 1 + getSizeRecursive(current.right);
}
public boolean containsNode(int value) {
return containsNodeRecursive(root, value);
}
private boolean containsNodeRecursive(Node current, int value) {
if (current == null) {
return false;
}
if (value == current.value) {
return true;
}
return value < current.value
? containsNodeRecursive(current.left, value)
: containsNodeRecursive(current.right, value);
}
public void delete(int value) {
root = deleteRecursive(root, value);
}
private Node deleteRecursive(Node current, int value) {
if (current == null) {
return null;
}
if (value == current.value) {
// Case 1: no children
if (current.left == null && current.right == null) {
return null;
}
// Case 2: only 1 child
if (current.right == null) {
return current.left;
}
if (current.left == null) {
return current.right;
}
// Case 3: 2 children
int smallestValue = findSmallestValue(current.right);
current.value = smallestValue;
current.right = deleteRecursive(current.right, smallestValue);
return current;
}
if (value < current.value) {
current.left = deleteRecursive(current.left, value);
return current;
}
current.right = deleteRecursive(current.right, value);
return current;
}
private int findSmallestValue(Node root) {
return root.left == null ? root.value : findSmallestValue(root.left);
}
public void traverseInOrder(Node node) {
if (node != null) {
traverseInOrder(node.left);
System.out.print(" " + node.value);
traverseInOrder(node.right);
}
}
public void traversePreOrder(Node node) {
if (node != null) {
System.out.print(" " + node.value);
traversePreOrder(node.left);
traversePreOrder(node.right);
}
}
public void traversePostOrder(Node node) {
if (node != null) {
traversePostOrder(node.left);
traversePostOrder(node.right);
System.out.print(" " + node.value);
}
}
public void traverseLevelOrder() {
if (root == null) {
return;
}
Queue<Node> nodes = new LinkedList<>();
nodes.add(root);
while (!nodes.isEmpty()) {
Node node = nodes.remove();
System.out.print(" " + node.value);
if (node.left != null) {
nodes.add(node.left);
}
if (node.left != null) {
nodes.add(node.right);
}
}
}
class Node {
int value;
Node left;
Node right;
Node(int value) {
this.value = value;
right = null;
left = null;
}
}
}
I have the following function is in class implementing a set of numbers as a binary search tree.The function checks if the input integer is in the tree.
public boolean isIn(int v){
if(root != null){
if(v == root.element){
System.out.print(root.element);
return true;
}
isIn(root.left.element);
isIn(root.right.element);
}
return false;
}
I am getting Exception in thread "main" java.lang.StackOverflowError if I check anything other than the first element of the tree with the function.
Edit:
My tree is setup as follows:
public class BSTSet{
private TNode root;
public BSTSet(){
root = null;
}
public BSTSet(int[] input){
int len = input.length;
for (int i = 0; i<len-1; i++ ) {
add(input[i]);
}
}
public void add(int v) {
if (root == null) {
root = new TNode( v, null,null);
return;
}
TNode node = root;
while (true) {
if (v < node.element) {
if (node.left == null) {
node.left = new TNode( v, null,null);
break;
}
node = node.left;
} else if(v>node.element){
if (node.right == null) {
node.right = new TNode(v, null,null);
break;
}
node = node.right;
}
else{
break;
}
}
}
You have a few problems. You are only every comparing the parameter with root.element. Also, v is supposed to be the int that the user wants to search for, and you pass in the different elements of the tree, not the value that the user is searching for:
isIn(root.left.element);
isIn(root.right.element);
Also you are ignoring the result of your recursive calls. You need to rethink your logic a little. You want to be passing a Node and an int (the search value) to the method. You can have an overloaded method for this:
public boolean isIn(int v){
return isIn(v, root);
}
And then have:
public boolean isIn(int v, Node node){
if(node != null){
if(v == node.element){
System.out.print(node.element);
return true;
}
return isIn(v, node.left) || isIn(v, node.right);
}
return false;
}
I am trying to implement a delete function for my BST class. I am trying to follow a few standard tutorials, and am good with everything besides my delete function. I don't get any errors, but it doesn't delete the intended node. I am recursively getting to the intended Node, returning the opposite side node if it only has one child, otherwise I am returning the smallest value from n.right.
Any help would be appreciated - Thanks!
public class BinaryTree {
private Node root = null;
private class Node {
private Node left;
private Node right;
private int data;
public Node(int data, Node left, Node right) {
this.data = data;
this.left = left;
this.right = right;
}
}
public boolean add(int data) {
root = add(root, data);
return true;
}
private Node add(Node node, int data) {
if (node == null) {
node = new Node(data, null, null);
}
else {
if (data < node.data) {
node.left = add(node.left, data);
}
else {
node.right = add(node.right, data);
}
}
return node;
}
// Helper function
private Node findMin(Node node) {
while (node.left != null) {
node = node.left;
}
return node;
}
private Node findMax(Node node) {
while (node.right != null) {
node = node.right;
}
return node;
}
private void inOrderTraversal(Node n) {
if (n == null) return;
else {
inOrderTraversal(n.left);
System.out.println(n.data);
inOrderTraversal(n.right);
}
}
public void inOrderTraversal() {
inOrderTraversal(root);
}
private Node deleteKey(Node n, int data) {
if (n == null) return n;
if (data < n.data) deleteKey(n.left, data);
else if (data > n.data) deleteKey(n.right, data);
else {
if (n.left == null) return n.right;
else if (n.right == null) return n.left;
n.data = findMin(n.right).data;
n.right = deleteKey(n.right, n.data);
}
return n;
}
public void deleteKey(int data) {
root = deleteKey(root, data);
}
public static void main(String[] args) {
BinaryTree bst = new BinaryTree();
bst.add(2);
bst.add(8);
bst.add(1);
bst.add(7);
bst.add(3);
bst.add(11);
bst.add(1);
bst.add(21);
bst.add(10);
bst.add(12);
bst.inOrderTraversal();
System.out.println("----------------");
bst.deleteKey(3);
bst.inOrderTraversal();
}
}
I think the problem is in your deleteKey function:
private Node deleteKey(Node n, int data) {
if (n == null) return n;
if (data < n.data)
n.left = deleteKey(n.left, data); // must reassign child here
else if (data > n.data)
n.right = deleteKey(n.right, data); // must reassign child here
else {
if (n.left == null) return n.right;
else if (n.right == null) return n.left;
n.data = findMin(n.right).data;
n.right = deleteKey(n.right, n.data); // this was correct
}
return n;
}
When data < n.data or data > n.data, you aren't updating the current node's leaves. So this was finding the appropriate node to delete, but it wasn't rebuilding the node branches properly on the way back up from the recursion.