Comparing two valus of Nodes in Binary search trees in java - java

hey I am new in the binary trees world and I am trying to compare to values to know which direction should I place the newly added node next.
for now, I tried to do CompareTo method but didn't succeed very much I am now trying to make a private method that will give me the value of the Nodes i would love some help
this is my code now I need to add to the if statement the comparing of nodes so I can proceed :
public void add(E data) {
if(root == null) {
return ;
}
if(root.getLeftSon() == null) {
root.setLeftSon((Node<E>) data);
}
else if(root.getRightSon() == null) {
root.setRightSon((Node<E>) data);
}
}

you have to use generics correctly. Parameter has to extend comparable so you can determinate how to sort it.
class BinaryTree<T extends Comparable<T>> {
Node<T> root;
public Node<T> addRecursive(Node<T> current, T value) {
if (current == null) {
return new Node<T>(value);
}
int ord = value.compareTo(current.value);
if (ord > 0) {
current.left = addRecursive(current.left, value);
} else if (ord < 0) {
current.right = addRecursive(current.right, value);
} else {
// value already exists
return current;
}
return current;
}
static class Node<T extends Comparable<T>> {
T value;
Node<T> left;
Node<T> right;
Node(T value) {
this.value = value;
right = null;
left = null;
}
}
}

Related

How to recursively removing an item from linkedList?

Implementing LinkedList in a recursive approach was a bit challenging to me, which I get stuck in implementing of its remove method and wonder how to keep reference to previous item in recursive?
MyLinkedList class
package linkedlist;
public class MyLinkedList {
private Integer value;
private MyLinkedList next;
public MyLinkedList() {
}
public MyLinkedList(Integer value) {
this.value = value;
}
public void add(Integer value) {
if (this.value == null) {
this.value = value;
} else if (this.next == null) {
this.next = new MyLinkedList(value);
} else {
this.next.add(value);
}
}
public MyLinkedList remove(Integer index) {
//
// if (index < 0) {
// return this;
// }
// if (index == 0) {
// return this.next;
// }
// this.next = remove(index - 1);
return this;
}
public Integer indexOf(Integer value) {
if (this.value.equals(value)) {
return 0;
} else if (this.next == null) {
return null;
} else {
return 1 + this.next.indexOf(value);
}
}
}
MyLinkedListTester class
package linkedlist;
public class MyLinkedListTester {
public static void main(String[] args) {
MyLinkedList myLinkedList = new MyLinkedList();
myLinkedList.add(1);
myLinkedList.add(2);
myLinkedList.add(3);
myLinkedList.add(4);
System.out.println("Index Of Array: " + myLinkedList.indexOf(3));
MyLinkedList linkedList = myLinkedList.remove(3);
}
}
As mentioned in the comments the iterative approach is easier and more efficient most of the time. Anyway I think you do this as an exercise because in Java you already have a LinkedList.
So first you have a kind of error in your thinking (as far as I'm aware of it). It's also a kind of bad design choice. You create your MyLinkedList and save the data right into it and the next is also of the class MyLinkedList but it's not a list, it's a Node. There should only be one List, and 0 - many nodes.
For example I can't figure out how to do a remove function that will return the removed Node (in your case MyLinkedList) and as well let you keep the list in case you remove the first element in your list.
If you are looking in the implementation that's why they use Nodes and it's also more logical (a list doesn't contain "List elements") and so on...
Some other remark: your indexOf funtion will return an error if you try to get a element that does not exist (1 + null => error).
So anyway. What you have to do is to create a Node. (btw if you really want a real LinkedList you can use generic instead of int/Integer).
Below I post my solution how to do it (may be better out there but that is how I would do it). I also wrote a toString method to see how the List looks like (and it works as far as I can say). In case you want to still use your code without the Node it should give you an idea how to solve your problem with remove. You can also put some of the logic into the Node class but for me Node is only a container and doesn't really contain any logic.
public class MyLinkedList {
private Node head;
public MyLinkedList() {
}
public class Node{
private int value;
private Node next = null;
public Node(int value){
this.value = value;
}
public int getValue(){
return value;
}
public Node getNext(){
return next;
}
public void setNext(Node next){
this.next = next;
}
}
public void add(int value) {
Node next = new Node(value);
if(head == null){
head = next;
} else {
addRecursive(head,next);
}
}
private void addRecursive(Node node, Node next) {
if(node.next == null){
node.setNext(next);
} else {
addRecursive(node.getNext(),next);
}
}
public Node remove(int index){
Node removeNode = head;
if(index == 0){
head = head.getNext();
} else {
removeNode = removeRecursive(head,index-1);
}
return removeNode;
}
private Node removeRecursive(Node node, int index){
Node removeNode = node.getNext();
if(index == 0){
node.setNext(removeNode.getNext());
} else {
removeNode = removeRecursive(node.getNext(),index-1);
}
return removeNode;
}
public int indexOf(int value) {
if (head == null){
return -1;
} else if (head.getValue() == value){
return 0;
} else {
return indexOfRecursive(head,value,0);
}
}
private int indexOfRecursive(Node node, int value, int index) {
if(node.getNext() == null){
return -1;
} else if(node.getNext().getValue() == value){
return index + 1;
} else {
return indexOfRecursive(node.getNext(),value,index+1);
}
}
#Override
public String toString(){
if(head == null){
return "";
} else {
return toStringRecursive(head,"["+head.getValue());
}
}
private String toStringRecursive(Node node, String output){
if(node.getNext() == null){
return output + "]";
} else {
return toStringRecursive(node.getNext(),output + ", " + node.getNext().getValue());
}
}
}

remove method for generic type binary search tree result in stack overflow problem

I have come across this lab problem about implementing a remove method for generic type binary search tree.
I have implemented a binary search tree of generic type.
I have learnt the binary search tree remove algorithm, and I try to deal with 3 cases when the parent node has "0 child", " 1 child" or "2 children".
I implement the code to remove a node but keeps resulting in a stack overflow problem, and I cannot find where's wrong in my code.
Any help will be appreciated.
public class BinarySearchTree<T extends Comparable<T>> {
private Node<T> _root; //Root node
public class Node<T extends Comparable<T>> {
public T get_value() {return _value;}
public void set_value(T _value) {this._value = _value;}
public Node<T> get_left() {return _left;}
public void set_left(Node<T> _left) {this._left = _left;}
public Node<T> get_right() {return _right;}
public void set_right(Node<T> _right) {this._right = _right;}
public Node<T> get_parent() {return _parent;}
public void set_parent(Node<T> _parent) {this._parent = _parent;}
T _value; // Node value
Node<T> _left; // Left child
Node<T> _right; // Right child
Node<T> _parent; // Parent node
public Node(T key, Node<T> parent, Node<T> left, Node<T> right) {
_value = key;
_left = left;
_right = right;
_parent = parent;
}
}
// Remove a node from the BST
private Node<T> remove(BinarySearchTree<T> bst, Node<T> z) {
Node<T> delNode = null;
if(bst._root == null){
delNode = null;
}
else{
Node<T> current = bst._root;
// find the position to delete
while(current!=null){
int compare = z.get_value().compareTo(current.get_value());
if(compare < 0){
current = current.get_left();
}
if(compare > 0){
current = current.get_right();
}
else{
// if node has two child,replace it with right minimum value
if (current._left!=null && current._right!=null){
delNode = current;
Node<T> successor = minimumKey(current.get_right());
current.set_value(successor.get_value());
remove(successor._value);
}
if (current._left!=null){
delNode = current;
remove(current._value);
current._left.set_parent(current._parent);
}
if (current._right!=null){
delNode = current;
remove(current._value);
current._right.set_parent(current._parent);
}
else{
delNode = current;
remove(current._value);
}
}
}
}
return delNode;
}
// remove a node value
public void remove(T key) {
Node<T> z, node;
if ((z = find(_root, key)) != null)
if ( (node = remove(this, z)) != null)
node = null;
}
public Node<T> minimumKey(Node<T> current) {
while (current._left != null) {
current = current._left;
}
return current;
}
}
You have an issue with your conditions. They should be:
if(compare < 0) {
current = current.get_left();
} else if(compare > 0) {
current = current.get_right();
} else {
...
As it is now, if compare < 0 is true, you execute both current = current.get_left(); and the else clause.
I'm not sure that's the only issue with your remove method, though.

Comparable types (objects) can't be compared

I am getting this mystical error:
The operator > is undefined for the argument type(s)
java.lang.Comparable, java.lang.Comparable
What the heck?
(here's the code)
public class BST<T extends Comparable<T>> {
public static class Node<P extends Comparable<P>> {
P val;
Node<P> left;
Node<P> right;
public Node() {
}
public Node(P val) {
this.val = val;
}
}
Node<T> root;
private void addValHelper(Node root, Node newNode) {
if (root.val > newNode.val) { // <-- ERROR IS HERE
if (root.left == null) {
root.left = newNode;
} else {
addValHelper(root.left, newNode);
}
} else {
if (root.right == null) {
root.right = newNode;
} else {
addValHelper(root.right, newNode);
}
}
}
}
Java doesn't have operator overloading. You can't compare Comparable types with >. You need to use root.val.compareTo(newNode.val) instead.
As an aside:
Comparable is an interface, not a class
You don't need to specify <P extends Comparable<P>>
It might make more sense to move the addValHelper code into the Node class itself
It might make sense for Node to implement Comparable.
This way, your code feels a lot more idiomatic and you don't expose fields of Node to BST.
public class BST<T implements Comparable<T>> {
private final Node<T> root;
/** Presumably this is run when a value is added.. */
private void addValueHelper(Node rootNode, Node newNode) {
rootNode.attachChild(newNode);
}
public static class Node implements Comparable<T> {
private final T val;
private Node left;
private Node right;
public Node(T val) {
this.val = val;
}
public int compareTo(Node other) {
return this.val.compareTo(other.val);
}
/**
* Takes the given node and compares it with the current node.
* If the current node is greater than the given node, the given node is placed to the left.
* Otherwise it is placed to the right.
*/
protected void attachChild(Node newNode) {
if (this.compareTo(newNode) == 1) {
if (this.left == null) {
this.left = newNode;
return;
}
this.left.attachChild(newNode);
return;
}
if (this.right == null) {
this.right = newNode;
return;
}
this.right.attachChild(newNode);
}
}
}

Java double LinkedList remove node

So the idea is to make a Double Ended Priority Queue so far I have got a tree like structure using 2 Linked Lists, I have and interface I have to stick with with no alterations to it. The problem I have got is I have to make 2 methods called getMost and getLeast which gets the most or least node and then makes that node null. But these 2 methods are proving quite difficult to make. How would you go about doing it?
I have tried using recursion but this is proving difficult as I have to select the tree by going tree.root but passing in tree.root into a recursive method always starts it from tree.root
Also I have tried what i have written in inspectLeast() and inspectMost() but Java passes by value not by reference. Any tips?
P.S Not allowed to use anything from java collections or java util.
public class PAS43DPQ implements DPQ
{
//this is the tree
TreeNode tree = new TreeNode();
//this is for the size of the array
int size = 0;
#Override
public Comparable inspectLeast() {
return tree.inspectLeast(tree.root);
}
#Override
public Comparable inspectMost() {
return tree.inspectMost(tree.root);
}
#Override
public void add(Comparable c)
{
tree.add(c);
size++;
}
#Override
public Comparable getLeast() {
if (tree.root != null){
}
return getLeast();
}
#Override
public Comparable getMost(){
Comparable most = getMost();
return most;
}
#Override
public boolean isEmpty() {
return (size > 0)?true:false;
}
#Override
public int size() {
return this.size;
}
class TreeNode{
private Comparable value;
private TreeNode left, right, root;
//constructors
public TreeNode() {}
public TreeNode(TreeNode t) {
this.value = t.value;
this.left = t.left;
this.right = t.right;
this.root = t.root;
}
public TreeNode(Comparable c) {
this.value = (int) c;
}
public void add(Comparable input){
if(root == null){
root = new TreeNode(input);
return;
} else {
insert(root, input);
}
}
public Comparable inspectLeast(TreeNode n){
if (n == null)
return null;
if (n.left == null){
TreeNode least = n;
return least.value;
}
return inspectLeast(n.left);
}
public Comparable inspectMost(TreeNode n){
if (n == null)
return null;
if (n.right == null){
TreeNode most = n;
return most.value;
}
return inspectMost(n.right);
}
public Comparable getMost(TreeNode n){
if(n.right == null)
return n.value;
return tree.getMost(right);
}
public void insert(TreeNode n, Comparable input){
if(input.compareTo(n.value) >= 0){
if (n.right == null) {
n.right = new TreeNode(input);
return;
}
else
insert(n.right, input);
}
if(input.compareTo(n.value) < 0){
if(n.left == null) {
n.left = new TreeNode(input);
return;
}
else
insert(n.left, input);
}
}
}
}
You should be able to modify your TreeNode.getMost(TreeNode n) and TreeNode.getLeast(TreeNode n) similar to the following:
public class TreeNode{
// Also, your parameter here seems to be superfluous.
public TreeNode getMost(TreeNode n) {
if (n.right == null) {
n.root.right = null;
return n;
}
return n.getMost(n);
}
}
Get least should be able to be modified in a similar fashion, but using left rather than right obviously.

Implementing splay() method for Binary Search Tree

I am trying to implement a splay(Node x) method for a Binary Search Tree. I have the leftRotation(Node x) and rightRotation(Node x) methods implemented correctly (atleast, I think they are...), but when I try to implement them in a splay(Node x) method, it calls itself in an infinite loop. Now, I know why it's doing that, but can't seem to figure out how to fix it.
Here is the leftRotation(Node x) method:
public void leftRotation(Node<E> x) {
if (x.getRightChild() == null) {
return;
}
Node<E> y = x.getRightChild();
x.setRightChild(y.getLeftChild());
if (y.getLeftChild() != null) {
y.getLeftChild().setParent(x);
}
y.setParent(x.getParent());
if (x.getParent() == null) {
root = y;
} else {
if (x == x.getParent().getLeftChild()) {
x.getParent().setLeftChild(y);
} else {
x.getParent().setRightChild(y);
}
}
y.setLeftChild(x);
x.setParent(y);
}
Here's the rightRotation(Node x) method:
public void rightRotation(Node<E> x) {
if (x.getLeftChild() == null) {
return;
}
Node<E> y = x.getLeftChild();
x.setRightChild(y.getRightChild());
if (y.getRightChild() != null) {
y.getRightChild().setParent(x);
}
y.setParent(x.getParent());
if (x.getParent() == null) {
root = y;
} else {
if (x == x.getParent().getRightChild()) {
x.getParent().setRightChild(y);
} else {
x.getParent().setLeftChild(y);
}
}
x.setRightChild(x);
x.setParent(y);
}
And here's the splay(Node x) method:
public void splay(Node<E> x) {
while (x.getParent() != null) {
if (x.isLeftChild && x.getParent().isLeftChild) {
this.rightRotation(x.getParent());
this.rightRotation(x);
} else if (x.isRightChild && x.getParent().isRightChild) {
this.leftRotation(x.getParent());
this.leftRotation(x);
} else if (x.isLeftChild && x.getParent().isRightChild) {
this.rightRotation(x);
this.leftRotation(x);
} else if (x.isRightChild() && x.getParent().isLeftChild()) {
this.leftRotation(x);
this.rightRotation(x);
} else if (x.isLeftChild && x.getParent() == root) {
this.rightRotation(x);
} else if (x.isRightChild && x.getParent() == root) {
this.leftRotation(x);
}
}
}
Any ideas on how to fix the infinite loop? It seems to be something to do with it not breaking out of the while(x.getParent() != null) statement in the splay(Node x) method, but when I went through the code using the debugger, the properties of the node seemed to be changing, so I don't really know where it's going wrong?
setLeftChild(Node leftChild) method:
public void setLeftChild(Node<E> leftChild) {
this.leftChild = leftChild;
if (leftChild != null) {
leftChild.setIsRightChild(true);
leftChild.setParent(this);
}
}
Apart from all the mistakes/bad things I pointed out in your code, here is the biggest one, in rightRotation :
x.setRightChild(x);
This creates a cycle in your tree, hence the infinite loop. You should have unit tested your methods. One other major error in your code is that your if - else if instructions do not have an else so there might be cases where nothing happens during an iteration... hence the infinite loop. It's not the case here because you considered all the cases (actually, you considered even more, and the two last ones will never be executed because the four first cases cover every possible case) but as a general remark, this was really dangerous to code it that way.
Here is the code of my own implementation of all these methods, which I deem cleaner :
public class BinaryTree<T extends Comparable<T>> {
private Node<T> root;
public void rebalance(Node<T> node) {
while (!node.isRoot()) rotation(node.getParent(), node.getChildKind().opposite());
}
private void rotation(Node<T> node, Side side) {
if (node.getChild(side.opposite()) == null) return;
Node<T> sideChild = node.getChild(side.opposite());
node.setChild(sideChild.getChild(side), side.opposite());
if (node.getParent() == null) setRoot(sideChild);
else node.getParent().setChild(sideChild, node.getChildKind());
sideChild.setChild(node, side);
}
private void setRoot(Node<T> root) {
this.root = root;
if (root != null) root.setRoot();
}
private static enum Side {
LEFT, RIGHT;
public Side opposite() { return this == LEFT ? RIGHT : LEFT; }
}
private static class Node<T extends Comparable<T>> {
private T value;
private Node<T> left, right, parent;
public Node(T value) { this(value, null, null, null); }
public Node(T value, Node<T> left, Node<T> right, Node<T> parent) {
setValue (value );
setLeft (left );
setRight (right );
setParent(parent);
}
public Node<T> setLeft(Node<T> left) {
this.left = left;
if (left != null) left.parent = this;
return this;
}
public Node<T> setRight(Node<T> right) {
this.right = right;
if (right != null) right.parent = this;
return this;
}
public Node<T> setChild(Node<T> child, Side side) { return side == Side.LEFT ? setLeft(child) : setRight(child); }
public Node<T> setRoot() { return setParent(null); }
private Node<T> setParent(Node<T> parent) {
this.parent = parent;
return this;
}
public Node<T> setValue(T value) {
this.value = notNull(value);
return this;
}
public boolean isRoot() { return parent == null; }
public boolean isLeftChild () { return isRoot() || getParent().getValue().compareTo(getValue()) > 0; }
public boolean isRightChild() { return isRoot() || !isLeftChild() ; }
public Node<T> getChild(Side side) { return side == Side.LEFT ? getLeft() : getRight(); }
public Side getChildKind() {
Check.isFalse(isRoot(), "This method is not defined on root nodes");
return isLeftChild() ? Side.LEFT : Side.RIGHT;
}
public T getValue () { return value ; }
public Node<T> getLeft () { return left ; }
public Node<T> getRight () { return right ; }
public Node<T> getParent() { return parent; }
}
}
Note : my tree is not always optimally rebalanced. I did this out of my head but I will check at Wikipedia to see what they say, I probably did not apply the right algorithm, but it works pretty fine already expect in pathologic cases.

Categories