When I print out the elements of this Binary Tree using my inOrder method, it prints: 0 0 0 0 0 0
Here is my Code:
public class BST {
class Node {
int data;
Node left;
Node right;
public Node(int data) {
data = data;
left = null;
right = null;
}
public Node root;
/**
* Method to insert a new node in order
* in our binary search tree
*/
public void insert(int data) {
root = insert(root, data);
}
public Node insert(Node node, int data){
if(node==null){
node = new Node(data);
}else if (data < node.data){
node.left = insert(node.left, data);
}else{
node.right = insert(node.right, data);
}
return node;
}
/**
Prints the node values in the "inorder" order.
*/
public void inOrder() {
inOrder(root);
}
private void inOrder(Node node) {
if (node == null)
return;
inOrder(node.left());
System.out.print(node.data + " ");
inOrder(node.right);
}
}
Main class:
public class Main {
public static void main(String[] args) {
BST tree = new BST();
tree.insert(6);
tree.insert(4);
tree.insert(8);
tree.insert(2);
tree.insert(1);
tree.insert(5);
tree.inOrder();
}
}
I have a feeling that it is something wrong in my insert method, I just can't figure out what. Any help in the right direction would be great, and sorry for being a noob!
In class Node your constructor is setting the constructor argument to itself instead of initializing the class variable.
Use the keyword this in your ctor to distinguish from constructor arguments and class variable.
Example:
public class Pair
{
private int left;
private int right;
public Pair(int left, int right) {
// the following 2 lines don't do anything
// it set's the argument "left = left" which is silly...
left = left;
right = right;
// with the `this` keyword we can correctly initialize our class properties
// and avoid name collision
this.left = left;
this.right = right;
}
}
Related
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.
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.
below is the code for BinaryTree.java insertion . Every time i insert a new node , the root is null.What i want , after 1st insert , root should not be null and it should remember the 1st insert and then for 2nd insert, the condition if (root ==null) should be false.
import java.util.LinkedList;
public class BinaryTree {
private BTNode root;
public int size;
public BinaryTree(){
this.root= null;
}
// public BTNode getRoot(){
// return this.root;
// }
public void insert(int data){
insert(data, root);
//calling insert function that takes data and root to insert
}
private void insert (int data, BTNode root){
//case 1: no element in binary tree
if (root == null){
// if root is null create a new BTNode and make it root
BTNode newN= new BTNode(data);
newN.setLeft(null);
newN.setRight(null);
root =newN;
//System.out.println(root.getData());
size++;
return;
//return root.getData();
}
//case2: tree not empty
//create a queue and traverse each node left-right
LinkedList<BTNode> q = new LinkedList<BTNode>();
q.addFirst(root);
while(!(q.isEmpty())){ //if queue not empty
BTNode temp= (BTNode) q.removeFirst();
//check left
if (temp.getLeft()==null){
//create a node and set left
BTNode newN= new BTNode(data);
newN.setLeft(null);
newN.setRight(null);
temp.setLeft(newN);
size++;
return;
//return root.getData();
}
else{
q.addLast(temp.getLeft());
}
//check right in case left is not null
if (temp.getRight()==null){
//create a node and set right
BTNode newN= new BTNode(data);
newN.setLeft(null);
newN.setRight(null);
temp.setRight(newN);
size++;
return;
//return root.getData();
}
else{
q.addLast(temp.getRight());
}
}//while loop ends here
return ;
}// insert(data,root) function ends here
}//class ends here
below is code for BTNode.java
public class BTNode {
int data;
private BTNode left=null;
private BTNode right=null;
public BTNode(){
}
public BTNode(int data){
this.data=data;
}
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public BTNode getLeft() {
return left;
}
public void setLeft(BTNode left) {
this.left = left;
}
public BTNode getRight() {
return right;
}
public void setRight(BTNode right) {
this.right = right;
}
}
TestMain.java
public class TestMain {
public static void main(String[] args){
BinaryTree btree = new BinaryTree();
btree.insert(1);
//System.out.println(btree.getRoot().getData());
btree.insert(2);
btree.insert(3);
btree.insert(4);
btree.insert(5);
btree.insert(6);
}
}
TestMain.Java
public class TestMain {
public static void main(String[] args){
BinaryTree btree = new BinaryTree();
btree.insert(1);
System.out.println(btree.getRoot().getData());
}
inside BinaryTree:
public BTNode getRoot(){
return this.root;
}
private void insert (int data, BTNode rootParameter){ // your problem is here
//case 1: no element in binary tree
if (root == null){
// if root is null create a new BTNode and make it root
BTNode newN= new BTNode(data);
newN.setLeft(null);
newN.setRight(null);
root =newN;
//System.out.println(root.getData());
size++;
return;
//return root.getData();
}
// other part of your code
}
the problem is that you are assigning your root to parameter but you should assign it to root variable outside of your method. you won't get null reference now.
I am trying to implement Binary tree in java and here is my code:
class TestClass {
public static void newnode(int a , Node root,){
root = new Node(a);
System.out.println(root.data); // Printing out 22
}
public static void main(String args[] ) throws IOException {
Node root = null;
newnode(22,root);
System.out.println(root.data); // Giving NullPointerException
}
}
class Node{
Node left ;
Node Right;
int data ;
Node(int dataa){
this.data = dataa;
}
}
I could not insert a new node in my tree , the value of root does not changesWhen i call newnode function I getting the correct value of my Root Node but in the main function it gives me null point exceptionWhy the value of root is not updating
class TestClass {
public static Node newnode(int a , Node root){
root = new Node(a);
System.out.println(root.data); // Printing out 22
return root;
}
public static void main(String args[] ) throws IOException {
Node root = null;
root = newnode(22,root);
System.out.println(root.data); // Giving NullPointerException
}
}
try this
You shouldn't design methods with a lot of input parameters, because testing will be more painful. Also, there is no need to pass null to method just to assign an object to it - this is poor design.
import java.io.IOException;
class TestClass {
// This method is useless, use Factory Design Pattern if you want
// to create such solution with multiple variants
public static Node newNode(int a) {
return new Node(a);
}
public static void main(String args[]) throws IOException {
Node root = newNode(22);
System.out.println(root.getData());
}
}
class Node {
private int data;
private Node left;
private Node right;
public Node(int data) {
this.data = data;
}
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;
}
}
I am trying to print a binary tree by BFS.
my implementation is with a PriorityQueue.
in the beginning i insert root into PriorityQueue.
then in loop, i pull a node from PriorityQueue, print it, and insert his childs(if thay are not null) into PriorityQueue.
why when inserting the second node, i get this exception:
Exception in thread "main" java.lang.ClassCastException: Node cannot be cast to java.lang.Comparable
this is my code:
class main:
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Tree tree = new Tree();
}
}
class Node:
public class Node {
public Node(){}
public Node(int num)
{
value = num;
}
private int value;
private Node left;
private Node right;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
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 tree:
public class Tree {
private Node root;
public Tree()
{
root = new Node(5);
Node node2 = new Node(2);
Node node10 = new Node(10);
Node node8 = new Node(8);
Node node6 = new Node(6);
Node node15 = new Node(15);
root.setRight(node10);
root.setLeft(node2);
node10.setRight(node15);
node10.setLeft(node8);
node8.setLeft(node6);
printToWidth(root);
}
public void printToWidth(Node node)
{
PriorityQueue<Node> queue = new PriorityQueue<Node>();
queue.add(node);
while( !(queue.isEmpty()))
{
Node n = queue.poll();
System.out.println(n.getValue());
if (n.getLeft() != null)
queue.add(n.getLeft());
if (n.getRight() != null)
queue.add(n.getRight());
}
System.out.println("end printToWidth");
}
}
You've got two options:
Make Node implement Comparable<Node>, so that the elements can be inserted according to their natural ordering. This is likely the easier of the two.
public int compareTo(Node other) {
return value - other.getValue();
}
Use a custom Comparator<Node> and supply a compare method there, with an initial capacity.
PriorityQueue<Node> queue = new PriorityQueue<Node>(10, new Comparator<Node>() {
public int compare(Node left, Node right) {
return left.getValue() - other.getValue();
}
});
The exception is telling you, make Node implement Comparable<Node>.
You can insert the first node because it has nothing to compare to, so the comparison is not needed.