Binary tree with add a node at a specific existing node - java

I'm trying to create a binary tree in Java to model the way in a perfect maze.
Each node Node<T> can have 2 children (Node<T> left and Node<T> right).
Each node is definited with T data as (x,y) coordinates.
For add a new node, I need to find the actual node (current position) :
previousPosition = actualPosition;
move();
tree.addNode(previousPosition, actualPosition);
And addNode must me search the node previousPosition for add a child (actualPosition) to left or rigth (depending of null child).
I need your help.
My code:
public class BinaryTree<T> {
// Root node pointer. Will be null for an empty tree.
private Node root;
/*
--Node--
The binary tree is built using this nested node class.
Each node stores one data element, and has left and right
sub-tree pointer which may be null.
The node is a "dumb" nested class -- we just use it for
storage; it does not have any methods.
*/
private static class Node<T> {
Node<T> left;
Node<T> right;
T data;
Node(T newData) {
left = null;
right = null;
data = newData;
}
}
...
...
...
private Node<T> insert(Node<T> node, T parent, T data) {
if(node.data.equals(parent)) {
if(node.left == null) {
node.left = new Node<T>(data);
} else if (node.right == null) {
node.right = new Node<T>(data);
} else {
System.out.println("Children are not nulls");
}
} else {
if(node.left != null) {
insert(node.left, parent, data);
}
if(node.right != null) {
insert(node.right, parent, data);
}
}
return node;
}
}

Related

How make an add Method with a BinarySearchTree in Java?

I am having trouble with my add method, I believe that the error occurs in the parameters passed in the public method, however I'm not sure if my private helper method is also not adding the correct variables.
Here are the instructions to my addMethod
The add(E) method may additionally call the assignFirst() method to assign the first attribute in case it should be changed. The add helper method should now assign each node's "parent" and "next" references when a new node is created.
• The "parent" parameter should reference a newly created node's parent node, so when
creating a new node, you can simply assign its parent to this parameter.
• The "prev" parameter should reference a newly created node's previous node, so when
creating a new node, you can simply update the "next" references in the appropriate
nodes. The tricky part is knowing what values to pass when you're calling the add
helper method. Here's the logic:
• If the add helper return value is to be a right child, then that right child's previous
node should be the same as its parent. The optional getPrevNode won't be helpful
here since the previous node will be the new node's parent, and the new node isn't
yet attached to the tree.
• If the add helper return value is to be a left child, then that left child's previous node
could be determined by the optional getPrevNode method, asking it for the node that
is before the current node parameter.
Here is my code:
public void add(E value)
{
this.root = add(root, value, root, null);
assignFirst();
}
// post: value added to tree so as to preserve binary search tree
private BSTNode<E> add(BSTNode<E> node, E value, BSTNode<E> parent, BSTNode<E> prev)
{
if (node == null)
{
node = new BSTNode<E>(value);
node.parent = parent;
node.next = prev;
this.numElements++;
}
else if (node.data.compareTo(value) > 0)
{
node.left = add(node.left, value, node , getPrevNode(node));
}
else if (node.data.compareTo(value) < 0)
{
node.right = add(node.right, value, node, node.parent);
}
return node;
}
private void assignFirst()
{
BSTNode<E> node = root;
while(node.left != null)
{
node = node.left;
}
first = node;
}
private BSTNode<E> getPrevNode(BSTNode<E> node)
{
if(node.left != null)
{
node = node.left;
while(node.right != null)
{
node = node.right;
}
return node;
}
else if(node.parent != null)
{
if(node.parent.right == node)
{
return node.parent;
}
if(node.parent.left == node)
{
while(node.parent != null && node.parent.left == node)
{
node = node.parent;
}
if(node == root)
{
return null;
}
else
{
return node.parent;
}
}
}
return null;
}
Here is some background information, however I'm leaving some methods out since they're irrelevant to what I am trying to figure out. Therefore I am cutting it short.
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;
}
}
}
This was a rigorous process, here's what I got
public void add(E value)
{
this.root = add(root, value, root, null);
assignFirst();
}
// post: value added to tree so as to preserve binary search tree
private BSTNode<E> add(BSTNode<E> node, E value, BSTNode<E> parent, BSTNode<E> prev)
{
if (node == null)
{
node = new BSTNode<E>(value);
node.parent = parent;
if(prev == null)
{
node.next = parent;
}
else
{
node.next = prev.next;
prev.next = node;
}
this.numElements++;
}
else if (node.data.compareTo(value) > 0)
{
node.left = add(node.left, value, node , getPrevNode(node));
}
else if (node.data.compareTo(value) < 0)
{
node.right = add(node.right, value, node, node);
}
return node;
}

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.

Cannot cast from inner class to class

I have a BinaryTree class which contains an inner class Node.
What I would like to do is to be able to insert some nodes in my BinaryTree tree by calling tree.insert(node). However, to keep it clean and consistent, I dont want to create an insert() method inside Node inner class. So I tried the code below, but I have an error: Cannot cast from BinaryTree.Node to BinaryTree.
What should I do?
BinaryTree class
public class BinaryTree {
Node root = null;
private class Node {
int value;
Node left;
Node right;
}
public BinaryTree(int v) {
root.value = v;
root.left = null;
root.right = null;
}
public void insert(Node n) {
/* Error */
if(n.value > root.value) ((BinaryTree) root.right).insert(n);
}
}
Main class
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
String[] str = sc.nextLine().split(" ");
BinaryTree tree;
for(int i = 0; i < str.length-1; i++) {
int val = Integer.parseInt(str[i]);
//tree.insert(node);
}
}
}
Thanks,
You don't need typecasting inside insert method. It should be like this:
public void insert(Node n) {
if(n.value > root.value)
insert(root.right);
}
To insert a node in a tree you need to define where to insert it, so your insert methods should be something like:
//insert a new node right to a node. not null safe
public void insert(Node newNode, Node rightTo) {
newNode.right = rightTo.right;
newNode.left = rightTo;
rightTo.right = newNode;
}
which does not require casting.
To find the rightTo node you could use:
//get the last node which has a value lower than `value`
//may return null
public Node getNodeWithValueLowerThan(int value) {
if(root == null) return null;
return getNodeWithValueLowerThan(root, value);
}
//recursive method. null safe
private Node getNodeWithValueLowerThan(Node node, int value) {
if(node == null) return null;
if(node.value > value) return node.left; //return previous node. may be null
return getNodeWithValueLowerThan(node.right, value);
}
To insert a node as a last node, you could use:
//insert a new node as last
public void insertLastNode(Node newNode) {
Node lastNode = getTail();
if(lastNode == null) {//empty tree
root = newNode;
return;
}
newNode.left = lastNode;
lastNode.right = newNode;
}
where getTail is something like:
//find last node
private Node getTail() {
if(root == null) return null;
return getTail(root);
}
//recursive method to find last node. not null safe
private Node getTail(Node node) {
if(node.right == null) return node;
return getTail(node.right);
}
Note: code was not tested so debug carefully.

Recurse within binary tree's node class

I have successfully written a method to print the values of all the nodes in the subtree rooted at a given node (code pasted below under the label "Working Code"). However, this printTree method is in the Main class (as opposed to being in the Node class itself). I am wondering if it is possible (and ideal?) to rewrite the code so that the printTree method is in the Node class itself? My attempt is below (code pasted below under the label "Non Working Code"), but it threw a Null Pointer Exception. Thank you!
WORKING CODE:
public class Node {
int value;
Node left;
Node right;
public Node(int value, Node left, Node right)
{
this.value = value;
this.left = left;
this.right = right;
}
}
public class Main {
public static void printTree(Node current)
{
if (current != null)
{
System.out.println(current.value);
printTree(current.left);
printTree(current.right);
}
return;
}
public static void main(String[] args) {
// write your code here
Node a = new Node(3, new Node(4, null, null), new Node(5, null, null));
printTree(a);
}
}
NON WORKING CODE (in Node class):
public void printTree()
{
Node current = this;
if (current != null)
{
System.out.println(current.value);
current.left.printTree();
current.right.printTree();
}
return;
}
The problem is not in the Node current = this; line. But in the
current.left.printTree();
current.right.printTree();
lines.
Because even when current is not null, current.left or current.right could be null. And you are trying to invoke printTree() on a null object.
Fix:
if (current != null)
{
System.out.println(current.value);
if (current.left != null)
current.left.printTree();
if (current.right != null)
current.right.printTree();
}

get root of a binary search tree in java

I have created a binary search tree in java that allow user to add nodes to the tree
This is my implementation of the binary tree in java which accept root node on creation and then automatically figure out that it should add the child into left side or right side of the tree.
public class BinarySearchTree {
Node root = null;
public BinarySearchTree(Node root){
this.root =root;
}
public void add(int data){
Node newNode = new Node(data);
if(this.root ==null){
newNode =this.root;
}
if(data>this.root.data){
addRight(root,newNode);
}
if(data<this.root.data){
addLeft(root,newNode);
}
}
public Node getRoot(){
return this.root;
}
private void addLeft(Node root, Node newNode) {
if(root.leftChild == null){
root.leftChild = newNode;
}
else {
this.root = this.root.leftChild;
add(newNode.data);
}
}
private void addRight(Node root,Node newNode) {
if (root.rightChild == null){
root.rightChild = newNode;
}
else {
this.root = this.root.rightChild;
add(newNode.data);
}
}
}
But when I try to retrieve the root node with getRoot() method. it return me the child of the root rather than the actual root node that I had passed in.
this is a example of using it
TreeHight treeHight = new TreeHight();
Node root = new Node(100);
BinarySearchTree unbalance = new BinarySearchTree(root);
unbalance.add(200);
unbalance.add(50);
unbalance.add(250);
unbalance.add(350);
when I try to get root node it give me 250 as the first node rather than 100.
How can I retrieve the root node of this tree ?
In your code you write:
this.root = this.root.leftChild;
add(newNode.data);
This is probably wrong behavior?
You should rewrite it to:
add(this.root.leftChild,newNode);
And then define a recursive method that looks whether the item should be stored left/right of the subroot.
Something like:
public void add(Node subroot, int data){
if(data > subroot.data){
addRight(subroot,data);
}
else if(data < subroot.data){
addLeft(subroot,newNode);
}
}
private void addLeft(Node subroot, int data) {
if(subroot.leftChild == null){
subroot.leftChild = new Node(data);
}
else {
add(subroot.leftChild,data);
}
}
private void addRight(Node subroot, int data) {
if(subroot.rightChild == null){
subroot.rightChild = new Node(data);
}
else {
add(subroot.rightChild,data);
}
}
And the add method is then:
public void add(int data){
if(this.root == null){
this.root = new Node(data);
}
else {
this.add(this.root,data);
}
}
I think an invariant of a binary tree is that the root remains the same. The same goes for addRight by the way.
Finally you also wrote:
newNode =this.root;
in your add method, this of course, doesn't make much sense.
You are editing the root in this line:
this.root = this.root.rightChild;
I think you should add the new node to the right recursively like this:
else {
addRight(this.root.rightChild, newNode);
}
And just as a note i think you have problem in this block "in the add method":
if(this.root ==null){
newNode =this.root; // it should be this.root = newNode;
}

Categories